增广路:
1 /************************************************************* 2 题目: Flow Problem(HDU 3549) 3 链接: http://acm.hdu.edu.cn/showproblem.php?pid=3549 4 题意: 给一个单向图,求从1到n的最大流 5 算法: 最大流之增广路(入门) 6 算法思想: 不断用BFS找通路,没每找一条路,记录这条路的最小流, 7 再给这条路上的所有流量减去这个最小值。 8 **************************************************************/ 9 #include<iostream> 10 #include<cstdio> 11 #include<cstring> 12 #include<algorithm> 13 #include<queue> 14 using namespace std; 15 16 int cap[20][20]; 17 int a[20],father[20]; 18 int n,m; 19 20 void Init() 21 { 22 memset(cap,0,sizeof(cap)); 23 memset(a,0,sizeof(a)); 24 } 25 26 int bfs() 27 { 28 queue<int>q; 29 int ans=0; 30 while (1) 31 { 32 while (!q.empty()) q.pop(); 33 memset(a,0,sizeof(a)); 34 a[1]=10000000; 35 q.push(1); 36 father[1]=-1; 37 while (!q.empty()) 38 { 39 int u=q.front(); 40 q.pop(); 41 for (int v=2;v<=n;v++) 42 { 43 if (!a[v]&&cap[u][v]>0) 44 { 45 q.push(v); 46 father[v]=u; 47 a[v]=min(a[u],cap[u][v]); 48 } 49 } 50 } 51 if (!a[n]) return ans; 52 for (int u=n;father[u]!=-1;u=father[u]) 53 { 54 cap[u][father[u]]+=a[n]; 55 cap[father[u]][u]-=a[n]; 56 } 57 ans+=a[n]; 58 59 } 60 } 61 62 int main() 63 { 64 int t,k=1; 65 scanf("%d",&t); 66 while (t--) 67 { 68 scanf("%d%d",&n,&m); 69 Init(); 70 int u,v,w; 71 while (m--) 72 { 73 scanf("%d%d%d",&u,&v,&w); 74 cap[u][v]+=w; 75 } 76 printf("Case %d: %d\n",k++,bfs()); 77 } 78 }
dinic:
1 /*************************************************************** 2 算法: 最大流之dinic(入门) 3 算法思想: dinic的主要思想是层次图和阻塞流,只保留每个节点 4 出发到下一个层次的弧,得到的图就叫层次图。阻塞 5 流就是不考虑反向弧时的极大流。先用bfs分层,再计 6 算阻塞流,不断从复这两步,直到找不到阻塞流结束。 7 ***************************************************************/ 8 #include<iostream> 9 #include<cstdio> 10 #include<cstring> 11 #include<algorithm> 12 #include<queue> 13 using namespace std; 14 15 int cap[20][20]; 16 int d[20]; 17 int n,m; 18 19 int bfs() 20 { 21 queue<int>q; 22 memset(d,0,sizeof(d)); 23 q.push(1); 24 while (!q.empty()) 25 { 26 int u=q.front(); 27 q.pop(); 28 for (int v=2;v<=n;v++) 29 { 30 if (!d[v]&&cap[u][v]>0) 31 { 32 q.push(v); 33 d[v]=d[u]+1; 34 } 35 } 36 } 37 return d[n]; 38 } 39 40 int dfs(int u,int w) 41 { 42 if (u==n||w==0) return w; 43 int ans=0; 44 for (int v=2;v<=n;v++) 45 { 46 if (cap[u][v]>0&&d[u]==d[v]-1) 47 { 48 int temp=dfs(v,min(w,cap[u][v])); 49 cap[u][v]-=temp; 50 cap[v][u]+=temp; 51 w-=temp; 52 ans+=temp; 53 } 54 } 55 return ans; 56 } 57 58 int dinic() 59 { 60 int ans=0; 61 while (bfs()) ans+=dfs(1,100000000); 62 return ans; 63 } 64 65 int main() 66 { 67 int t,k=1; 68 scanf("%d",&t); 69 while (t--) 70 { 71 scanf("%d%d",&n,&m); 72 memset(cap,0,sizeof(cap)); 73 int u,v,w; 74 while (m--) 75 { 76 scanf("%d%d%d",&u,&v,&w); 77 cap[u][v]+=w; 78 } 79 printf("Case %d: %d\n",k++,dinic()); 80 } 81 }
dinic之邻接表建图:
1 /************************************************ 2 算法: 最大流之dinic(邻接表建图) 3 *************************************************/ 4 5 #include<iostream> 6 #include<cstdio> 7 #include<cstring> 8 #include<algorithm> 9 #include<queue> 10 using namespace std; 11 12 const int mx=1005; 13 struct Eage 14 { 15 int u,v; 16 int next,cap; 17 }; 18 Eage eage[mx*2]; 19 int head[mx]; 20 int d[mx]; 21 int pos; 22 int n,m; 23 24 void Init() 25 { 26 memset(head,-1,sizeof(head)); 27 pos=0; 28 } 29 30 void add(int u,int v,int w) 31 { 32 eage[pos].v=v; 33 eage[pos].cap=w; 34 eage[pos].next=head[u]; 35 head[u]=pos++; 36 } 37 38 int bfs() 39 { 40 queue<int>q; 41 memset(d,0,sizeof(d)); 42 d[1]=1; 43 q.push(1); 44 while (!q.empty()) 45 { 46 int u=q.front(); 47 q.pop(); 48 for (int i=head[u];i!=-1;i=eage[i].next) 49 { 50 int v=eage[i].v; 51 if (!d[v]&&eage[i].cap>0) 52 { 53 d[v]=d[u]+1; 54 q.push(v); 55 } 56 } 57 } 58 return d[n]; 59 } 60 61 int dfs(int u,int w) 62 { 63 if (u==n||w==0) return w; 64 int ans=0; 65 for (int i=head[u];i!=-1;i=eage[i].next) 66 { 67 int v=eage[i].v; 68 if (d[u]==d[v]-1&&eage[i].cap>0) 69 { 70 int temp=dfs(v,min(w,eage[i].cap)); 71 eage[i].cap-=temp; 72 eage[i^1].cap+=temp; 73 w-=temp; 74 ans+=temp; 75 } 76 } 77 return ans; 78 } 79 80 int dinic() 81 { 82 int ans=0; 83 while (bfs()) ans+=dfs(1,10000000); 84 return ans; 85 } 86 87 int main() 88 { 89 int t,k=1; 90 scanf("%d",&t); 91 while (t--) 92 { 93 Init(); 94 scanf("%d%d",&n,&m); 95 int u,v,w; 96 while (m--) 97 { 98 scanf("%d%d%d",&u,&v,&w); 99 add(u,v,w); 100 add(v,u,0); 101 } 102 printf("Case %d: %d\n",k++,dinic()); 103 } 104 }