题目链接:http://acm.nbu.edu.cn/v1.0/Problems/Problem.php?pid=2430
题目大意:
有n个城市(编号1~n),m条管道,每条管道连接两个城市,管道i最多可容纳c[i]的能量通过,求从1最多能向n传送多少能量。
0<=n<=200,0<=m<=40000,0<=ci<=100000.
题目思路:
裸的最大流,按照题意建图,1为源点,n为汇点,求最大流。
代码:
#include <stdlib.h> #include <string.h> #include <stdio.h> #include <ctype.h> #include <math.h> #include <stack> #include <queue> #include <map> #include <set> #include <vector> #include <string> #include <iostream> #include <algorithm> using namespace std; #define ll __int64 #define ls rt<<1 #define rs ls|1 #define lson l,mid,ls #define rson mid+1,r,rs #define middle (l+r)>>1 #define eps (1e-8) #define clr_all(x,c) memset(x,c,sizeof(x)) #define clr(x,c,n) memset(x,c,sizeof(x[0])*(n+1)) #define MOD (1000000007) #define inf (0x3f3f3f3f) #define pi (acos(-1.0)) #define _max(x,y) (((x)>(y))? (x):(y)) #define _min(x,y) (((x)<(y))? (x):(y)) #define _abs(x) ((x)<0? (-(x)):(x)) #define getmin(x,y) ((x)= ((x)<0 || (y)<(x))? (y):(x)) #define getmax(x,y) ((x)= ((y)>(x))? (y):(x)) template <class T> void _swap(T &x,T &y){T t=x;x=y;y=t;} int TS,cas=1; const int M=200+5; int n,m; struct sap{ typedef ll type; struct edge{ int to,next; type flow; }edg[999999]; int n,m; int g[M],cur[M],pre[M]; int dis[M],gap[M]; int q[M],head,tail; void init(int _n){n=_n,m=0,clr_all(g,-1);} void insert(int u,int v,type f,type c=0){ edg[m].to=v,edg[m].flow=f,edg[m].next=g[u],g[u]=m++; edg[m].to=u,edg[m].flow=0,edg[m].next=g[v],g[v]=m++; } bool bfs(int s,int t){ clr(gap,0,n),clr(dis,-1,n); gap[dis[t]=0]++,dis[s]=-1; for(q[head=tail=0]=t;head<=tail;){ int u=q[head++]; for(int i=g[u];i!=-1;i=edg[i].next){ edge& e=edg[i],ee=edg[i^1]; if(dis[e.to]==-1 && ee.flow>0){ gap[dis[e.to]=dis[u]+1]++; q[++tail]=e.to; } } } return dis[s]!=-1; } type maxFlow(int s,int t){ if(!bfs(s,t)) return 0; type res=0,a; int i; for(i=0;i<n;i++) cur[i]=g[i]; pre[s]=s,cur[s]=g[s],cur[t]=g[t]; for(int u=s;dis[s]<n;){ if(u==t){ for(a=-1;u!=s;u=pre[u]) getmin(a,edg[cur[pre[u]]].flow); for(u=t;u!=s;u=pre[u]){ edg[cur[pre[u]]].flow-=a; edg[cur[pre[u]]^1].flow+=a; } res+=a; } bool ok=0; for(i=cur[u];i!=-1;i=edg[i].next){ edge& e=edg[i]; if(dis[u]==dis[e.to]+1 && e.flow>0){ cur[u]=i,pre[e.to]=u,u=e.to; ok=1;break; } } if(ok) continue; int mindis=n-1; for(i=g[u];i!=-1;i=edg[i].next){ edge& e=edg[i]; if(mindis>dis[e.to] && e.flow>0) mindis=dis[e.to],cur[u]=i; } if(--gap[dis[u]]==0) break; gap[dis[u]=mindis+1]++,u=pre[u]; } return res; } }p; void run(){ int i,j; p.init(n); while(m--){ int s,e; ll c; scanf("%d%d%I64d",&s,&e,&c); p.insert(s-1,e-1,c); } printf("%I64d\n",p.maxFlow(0,n-1)); } void preSof(){ } int main(){ //freopen("input.txt","r",stdin); //freopen("output.txt","w",stdout); preSof(); //run(); while(~scanf("%d%d",&n,&m)) run(); //for(scanf("%d",&TS);cas<=TS;cas++) run(); return 0; }