题目:http://poj.org/problem?id=3469
最小割水题(竟然没能1A);
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; int const maxn=2e4+5,maxm=2e5+5,inf=0x3f3f3f3f; int n,m,hd[maxn],d[maxn],ct=1,cur[maxn],ans; queue<int>q; struct N{ int to,nxt,w; N(int t=0,int n=0,int w=0):to(t),nxt(n),w(w) {} }ed[(maxn+maxm)<<2]; void add(int x,int y,int z) { ed[++ct]=N(y,hd[x],z); hd[x]=ct; ed[++ct]=N(x,hd[y],0); hd[y]=ct; } bool bfs() { while(q.size())q.pop(); memset(d,0,sizeof d); q.push(0); d[0]=1; while(q.size()) { int x=q.front(); q.pop(); for(int i=hd[x],u;i;i=ed[i].nxt) if(!d[u=ed[i].to]&&ed[i].w)d[u]=d[x]+1,q.push(u); } return d[n+1]; } int dfs(int x,int f) { if(x==n+1)return f; int res=0; for(int &i=cur[x],u;i;i=ed[i].nxt) { if(d[u=ed[i].to]==d[x]+1&&ed[i].w) { int k=dfs(u,min(ed[i].w,f-res));//f-res!!! res+=k; ed[i].w-=k; ed[i^1].w+=k; if(res==f)return f; } } if(!res)d[x]=0; return res; } int main() { scanf("%d%d",&n,&m); for(int i=1,a,b;i<=n;i++) { scanf("%d%d",&a,&b); add(0,i,a); add(i,n+1,b); } for(int i=1,x,y,z;i<=m;i++) { scanf("%d%d%d",&x,&y,&z); add(x,y,z); add(y,x,z); } while(bfs()) { memcpy(cur,hd,sizeof hd); ans+=dfs(0,inf); } printf("%d",ans); return 0; }