Drainage Ditches(Dinic最大流)
http://poj.org/problem?id=1273
用Dinic求最大流的模板题,注意会有重边。
邻接矩阵建图
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<stdio.h> 2 #include<string.h> 3 #include<queue> 4 #include<algorithm> 5 using namespace std; 6 const int maxn = 510; 7 const int INF = 0x3f3f3f3f; 8 int flow[maxn][maxn];//残量 9 int m,n; 10 int dis[maxn]; 11 int bfs()//按层数“建”图,就是对每层的点用dis标记它到源点的层数 12 { 13 queue<int>que; 14 memset(dis,-1,sizeof(dis)); 15 while(!que.empty()) 16 que.pop(); 17 dis[1] = 0; 18 que.push(1); 19 20 while(!que.empty()) 21 { 22 int u = que.front(); 23 que.pop(); 24 25 for(int i = 1; i <= n; i++) 26 { 27 if(flow[u][i] > 0 && dis[i] < 0) 28 { 29 dis[i] = dis[u]+1; 30 que.push(i); 31 } 32 } 33 } 34 35 if(dis[n] > 0) 36 return 1; 37 else return 0; 38 } 39 //dfs寻找路径上的最小流量 40 int dfs(int s, int mf) 41 { 42 int a; 43 if(s == n) 44 return mf; 45 for(int i = 1; i <= n; i++) 46 { 47 if(dis[i] == dis[s] + 1 && flow[s][i] > 0 && (a = dfs(i,min(mf,flow[s][i])))) 48 { 49 flow[s][i] -= a; 50 flow[i][s] += a; 51 return a; 52 } 53 } 54 return 0; 55 } 56 57 int main() 58 { 59 while(~scanf("%d %d",&m,&n)) 60 { 61 int u,v,w; 62 memset(flow,0,sizeof(flow)); 63 for(int i = 0; i < m; i++) 64 { 65 scanf("%d %d %d",&u,&v,&w); 66 flow[u][v] += w; 67 } 68 int ans = 0,res; 69 while(bfs())//bfs寻找源点到汇点是否有路 70 { 71 res = dfs(1,INF); 72 if(res > 0) 73 ans += res; 74 } 75 printf("%d\n",ans); 76 } 77 return 0; 78 79 }
邻接表建图
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<stdio.h> 2 #include<string.h> 3 #include<queue> 4 #include<algorithm> 5 using namespace std; 6 const int maxn = 510; 7 const int INF = 0x3f3f3f3f; 8 int m,n,cnt; 9 struct node 10 { 11 int u,v,w; 12 int next; 13 }edge[maxn]; 14 int p[maxn]; 15 int dis[maxn]; 16 void add(int u, int v, int w) 17 { 18 19 edge[cnt].u = u; 20 edge[cnt].v = v; 21 edge[cnt].w = w; 22 edge[cnt].next = p[u]; 23 p[u] = cnt++; 24 25 edge[cnt].u = v; 26 edge[cnt].v = u; 27 edge[cnt].w = 0; 28 edge[cnt].next = p[v]; 29 p[v] = cnt++; 30 } 31 32 int bfs() 33 { 34 queue<int> que; 35 while(!que.empty()) 36 que.pop(); 37 memset(dis,-1,sizeof(dis)); 38 dis[1] = 0; 39 que.push(1); 40 41 while(!que.empty()) 42 { 43 int u = que.front(); 44 que.pop(); 45 46 for(int i = p[u]; i != -1; i = edge[i].next) 47 { 48 if(edge[i].w > 0 && dis[ edge[i].v ] < 0) 49 { 50 dis[ edge[i].v ] = dis[u] + 1; 51 que.push(edge[i].v); 52 } 53 } 54 } 55 if(dis[n] > 0) 56 return 1; 57 else return 0; 58 } 59 60 int dfs(int s, int mf) 61 { 62 if(s == n) 63 return mf; 64 int a; 65 int tf = 0; 66 for(int i = p[s]; i != -1; i = edge[i].next) 67 { 68 int v = edge[i].v; 69 int w = edge[i].w; 70 if(dis[v] == dis[s] + 1 && w > 0 && (a = dfs(v,min(mf,w)))) 71 { 72 edge[i].w -= a; 73 edge[i^1].w += a; 74 return a; 75 } 76 } 77 if(!tf)//若找不到小流,从这个点到不了汇点,把这个点从分层图删去 78 dis[s] = -1; 79 return tf; 80 } 81 82 int main() 83 { 84 while(~scanf("%d %d",&m,&n)) 85 { 86 int u,v,w; 87 cnt = 0; 88 memset(p,-1,sizeof(p)); 89 for(int i = 0; i < m; i++) 90 { 91 scanf("%d %d %d",&u,&v,&w); 92 add(u,v,w); 93 } 94 int ans = 0; 95 int res; 96 while(bfs()) 97 { 98 res = dfs(1,INF); 99 if(res > 0) 100 ans += res; 101 } 102 printf("%d\n",ans); 103 } 104 105 return 0; 106 }