Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 19857 Accepted Submission(s): 9510
Problem Description
Every time it rains on Farmer John's fields, a pond forms over Bessie's favorite clover patch. This means that the clover is covered by water for awhile and takes quite a long time to regrow. Thus, Farmer John has built a set of drainage ditches so that Bessie's clover patch is never covered in water. Instead, the water is drained to a nearby stream. Being an ace engineer, Farmer John has also installed regulators at the beginning of each ditch, so he can control at what rate water flows into that ditch.
Farmer John knows not only how many gallons of water each ditch can transport per minute but also the exact layout of the ditches, which feed out of the pond and into each other and stream in a potentially complex network.
Given all this information, determine the maximum rate at which water can be transported out of the pond and into the stream. For any given ditch, water flows in only one direction, but there might be a way that water can flow in a circle.
Input
The input includes several cases. For each case, the first line contains two space-separated integers, N (0 <= N <= 200) and M (2 <= M <= 200). N is the number of ditches that Farmer John has dug. M is the number of intersections points for those ditches. Intersection 1 is the pond. Intersection point M is the stream. Each of the following N lines contains three integers, Si, Ei, and Ci. Si and Ei (1 <= Si, Ei <= M) designate the intersections between which this ditch flows. Water will flow through this ditch from Si to Ei. Ci (0 <= Ci <= 10,000,000) is the maximum rate at which water will flow through the ditch.
Output
For each case, output a single integer, the maximum rate at which water may emptied from the pond.
Sample Input
5 4
1 2 40
1 4 20
2 4 20
2 3 30
3 4 10
50
EK邻接矩阵
#include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> #include<string> #include<vector> #include<queue> #define maxn 210 #define inf 0x3f3f3f using namespace std; int g[maxn][maxn]; bool used[maxn]; int linker[maxn]; int m; void net(int u,int flow) { while(linker[u]!=-1) { g[linker[u]][u]-=flow; g[u][linker[u]]+=flow; u=linker[u]; } } int bfs(int s,int t) { memset(used,false,sizeof(used)); memset(linker,-1,sizeof(linker)); used[s]=true; int minn=inf; queue<int>q; q.push(s); while(!q.empty()) { int cur=q.front(); q.pop(); if(cur==t)break; for(int i=1;i<=m;i++) { if(!used[i]&&g[cur][i]) { q.push(i); minn=minn<g[cur][i]?minn:g[cur][i]; linker[i]=cur; used[i]=true; } } } if(linker[t]==-1) return 0; return minn; } int ek(int s,int t) { int an=0,ans=0; do{ an=bfs(s,t); ans+=an; net(t,an); }while(an!=0); return ans; } int main() { int n; while(~scanf("%d%d",&n,&m)) { memset(g,0,sizeof(g)); for(int i=0;i<n;i++) { int x,y,z; cin>>x>>y>>z; g[x][y]+=z; } cout<<ek(1,m)<<endl; } }
dinic:邻接矩阵
#include<map> #include<set> #include<queue> #include<math.h> #include<vector> #include<string> #include<stdio.h> #include<iostream> #include<string.h> #include<algorithm> #define inf 0x3f3f3f #define ll long long #define maxn 300 using namespace std; int g[maxn][maxn]; bool used[maxn]; int deepth[maxn]; int s,t; bool bfs(){ memset(deepth,0,sizeof(deepth)); queue<int>q; deepth[s]=1;q.push(s); while(!q.empty()){ int cur=q.front();q.pop(); for(int i=1;i<=t;i++){ if(deepth[i]==0&&g[cur][i]){ deepth[i]=deepth[cur]+1;q.push(i); } } }if(deepth[t]==0)return false; return true; } int dfs(int cur,int dist){ if(cur==t)return dist; for(int i=1;i<=t;i++){ if(deepth[i]==deepth[cur]+1&&g[cur][i]){ int dis=dfs(i,min(dist,g[cur][i])); if(dis>0){ g[cur][i]-=dis;g[i][cur]+=dis; return dis; } } }return 0; } int dinic(){ int ans=0; while(bfs()){ while(int d=dfs(s,inf)){ ans+=d; } }return ans; } int main(){ int n,m; while(~scanf("%d%d",&n,&m)){ memset(g,0,sizeof(g)); for(int i=0;i<n;i++){ int a,b,c;scanf("%d%d%d",&a,&b,&c); g[a][b]+=c;} s=1;t=m; cout<<dinic()<<endl; } }
Flow Problem
Time Limit: 5000/5000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 18241 Accepted Submission(s): 8584
Problem Description
Network flow is a well-known difficult problem for ACMers. Given a graph, your task is to find out the maximum flow for the weighted directed graph.
Input
The first line of input contains an integer T, denoting the number of test cases.
For each test case, the first line contains two integers N and M, denoting the number of vertexes and edges in the graph. (2 <= N <= 15, 0 <= M <= 1000)
Next M lines, each line contains three integers X, Y and C, there is an edge from X to Y and the capacity of it is C. (1 <= X, Y <= N, 1 <= C <= 1000)
Output
For each test cases, you should output the maximum flow from source 1 to sink N.
Sample Input
2
3 2
1 2 1
2 3 1
3 3
1 2 1
2 3 1
1 3 1
Sample Output
Case 1: 1
Case 2: 2
dinic:邻接表(自己写的,很**)
#include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> #include<string> #include<vector> #include<queue> #define maxn 1100 #define inf 0x3f3f3f using namespace std; struct node { int v,w; struct node *next; }*h[maxn]; int d[maxn]; int s,t; void w(int u,int v,int w) { if(h[u]!=NULL) { struct node*q; for(q=h[u]; q!=NULL; q=q->next) { if(q->v==v) { q->w+=w; return; } } } struct node*p=(struct node*)malloc(sizeof(struct node)); p->w=w; p->v=v; p->next=h[u]; h[u]=p; } bool bfs() { queue<int>q; while(!q.empty())q.pop(); memset(d,0,sizeof(d)); d[s]=1; q.push(s); do{ int u=q.front(); q.pop(); struct node*T; for(T=h[u];T!=NULL;T=T->next) { if((T->w)>0&&d[T->v]==0) { d[T->v]=d[u]+1; q.push(T->v); } } }while(!q.empty()); if(d[t]==0)return false; else return true; } int dfs(int u,int dist) { if(u==t) return dist; struct node *p; for(p=h[u];p!=NULL;p=p->next) { if((d[p->v]==d[u]+1)&&(p->w)>0) { int di=dfs(p->v,min(dist,p->w)); if(di>0) { w(u,p->v,-di); w(p->v,u,di); return di; } } } return 0; } int dinic() { int ans=0; while(bfs()) { while(int d=dfs(s,inf)) { ans+=d; } } return ans; } int main() { int l,m=0; scanf("%d",&l); while(l--) { m++; for(int i=0;i<maxn;i++) h[i]=NULL; memset(d,0,sizeof(d)); s=1; int n; scanf("%d%d",&t,&n); for(int i=0;i<n;i++) { int x,y,z; cin>>x>>y>>z; w(x,y,z); w(y,x,0); } printf("Case %d: %d ",m,dinic()); } }
dinic:邻接表(大佬写的,很牛*)
#include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> #include<string> #include<vector> #include<queue> #define maxn 1100 #define inf 0x3f3f3f #define OPT(_)(hip+(((_)-hip)^1)) using namespace std; struct node{ int v,w; struct node *next; }hip[maxn*40],*hop; node *h[maxn]; int d[maxn]; int s,t; void w(int u,int v,int w,int b){ hop->v=v; hop->w=w; hop->next=h[u]; h[u]=hop++; hop->v=u; hop->w=b; hop->next=h[v]; h[v]=hop++; } bool bfs(){ queue<int>q; while(!q.empty())q.pop(); memset(d,0,sizeof(d)); d[s]=1; q.push(s); do{ int u=q.front(); q.pop(); struct node*T; for(T=h[u];T!=NULL;T=T->next){ if((T->w)>0&&d[T->v]==0){ d[T->v]=d[u]+1; q.push(T->v); } } }while(!q.empty()); if(d[t]==0)return false; else return true; } int dfs(int u,int dist){ if(u==t) return dist; struct node *p; for(p=h[u];p!=NULL;p=p->next){ if((d[p->v]==d[u]+1)&&(p->w)>0){ int di=dfs(p->v,min(dist,p->w)); if(di>0){ p->w-=di; OPT(p)->w+=di; return di; } } } return 0; } int dinic(){ int ans=0; while(bfs()){ while(int d=dfs(s,inf)){ ans+=d;} } return ans;} int main(){ int l,m=0; scanf("%d",&l); while(l--){ m++; for(int i=0;i<maxn;i++) h[i]=NULL; memset(d,0,sizeof(d)); hop=hip; s=1; int n; scanf("%d%d",&t,&n); for(int i=0;i<n;i++){ int x,y,z; cin>>x>>y>>z; w(x,y,z,0); } printf("Case %d: %d ",m,dinic()); } }