nbu 2430 war of energy

来源:互联网 发布:毕业证复印件制作软件 编辑:程序博客网 时间:2024/05/01 09:44

题目链接: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;}