1 /****************************************************************** 2 题目: Drainage Ditches(POJ 1273) 3 链接: http://poj.org/problem?id=1273 4 题意: 现在有m个池塘(从1到m开始编号,1为源点,m为汇点),及n条 5 水渠,给出这n条水渠所连接的池塘和所能流过的水量,求水 6 渠中所能流过的水的最大容量.水流是单向的。 7 算法: 最大流之增广路(入门) 8 算法思路: 不断用BFS找通路,没每找一条路,记录这条路的最小流,再 9 给这条路上的所有流量减去这个最小值。 10 *********************************************************************/ 11 #include<cstdio> 12 #include<iostream> 13 #include<cstring> 14 #include<algorithm> 15 #include<queue> 16 using namespace std; 17 18 const int mx=222; 19 int cap[mx][mx]; ///两个端点的流量。 20 int flow[mx][mx]; ///两个端点已用的流量。 21 int a[mx],father[mx]; 22 int m,n; 23 24 int bfs() 25 { 26 queue<int>q; 27 int ans=0; 28 father[1]=-1; 29 while (1) 30 { 31 memset(a,0,sizeof(a)); 32 a[1]=1000000000; 33 q.push(1); 34 ///找增广路 35 while (!q.empty()) 36 { 37 int u=q.front(); 38 q.pop(); 39 for (int v=2;v<=n;v++) 40 { 41 if (!a[v]&&cap[u][v]>flow[u][v]) 42 { 43 father[v]=u; 44 q.push(v); 45 a[v]=min(a[u],cap[u][v]-flow[u][v]); 46 } 47 } 48 } 49 if (a[n]==0) return ans; 50 for (int u=n;father[u]!=-1;u=father[u]) 51 { 52 flow[u][father[u]]-=a[n]; ///更新反向流量 53 flow[father[u]][u]+=a[n]; ///更新正向流量 54 } 55 ans+=a[n]; 56 } 57 } 58 59 int main() 60 { 61 while (~scanf("%d%d",&m,&n)) 62 { 63 memset(cap,0,sizeof(cap)); 64 memset(flow,0,sizeof(flow)); 65 int u,v,w; 66 while (m--) 67 { 68 scanf("%d%d%d",&u,&v,&w); 69 cap[u][v]+=w; 70 } 71 int ans=bfs(); 72 printf("%d\n",ans); 73 } 74 }
1 /********************************************************* 2 题目: Drainage Ditches(poj 1273) 3 算法: 最大流之dinic(入门) 4 算法思想: dinic的主要思想是层次图和阻塞流,只保留每个节点 5 出发到下一个层次的弧,得到的图就叫层次图。阻塞 6 流就是不考虑反向弧时的极大流。先用bfs分层,再计 7 算阻塞流,不断从复这两步,直到找不到阻塞流结束。 8 ************************************************************/ 9 #include<cstdio> 10 #include<cstring> 11 #include<algorithm> 12 #include<iostream> 13 #include<queue> 14 using namespace std; 15 16 const int mx=222; 17 int map[mx][mx]; 18 int d[mx]; 19 int m,n; 20 21 ///分层 22 int bfs() 23 { 24 queue<int>q; 25 memset(d,0,sizeof(d)); 26 q.push(1); 27 while (!q.empty()) 28 { 29 int u=q.front(); 30 q.pop(); 31 for (int v=2;v<=n;v++) 32 { 33 if (!d[v]&&map[u][v]>0) 34 { 35 d[v]=d[u]+1; 36 q.push(v); 37 } 38 } 39 } 40 return d[n]; 41 } 42 43 ///计算阻塞流 44 int dfs(int u,int w) 45 { 46 if (u==n||w==0) return w; 47 int ans=0; 48 int temp; 49 for (int v=2;v<=n;v++) 50 { 51 if (map[u][v]>0&&d[u]==d[v]-1) 52 { 53 int temp=dfs(v,min(w,map[u][v])); 54 ans+=temp; 55 map[u][v]-=temp; ///正向更新 56 map[v][u]+=temp; ///方向更新 57 w-=temp; ///从v流出的流量不能大于w。 58 } 59 } 60 return ans; 61 } 62 63 ///dinic算法 64 int dinic() 65 { 66 int ans=0; 67 while (bfs()) 68 ans+=dfs(1,1000000000); 69 return ans; 70 } 71 72 int main() 73 { 74 while (~scanf("%d%d",&m,&n)) 75 { 76 memset(map,0,sizeof(map)); 77 int u,v,w; 78 while (m--) 79 { 80 scanf("%d%d%d",&u,&v,&w); 81 map[u][v]+=w; 82 } 83 printf("%d\n",dinic()); 84 } 85 }