poj 1273 Drainage Ditches (网络流 最大流)
网络流模板题。
==========================================================================================================
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<queue> using namespace std; typedef long long LL; const LL INF = 1e9+7; const LL maxn = 1005; const LL MOD = 1e9+7; int n, m, Head[maxn], k; int Pre[maxn]; bool vis[maxn]; struct Edge { int from, to, w; int next; }edge[maxn*2]; void Init() { memset(Head, -1, sizeof(Head)); memset(Pre, -1, sizeof(Pre)); } void AddEdge(int s,int e,int w) { edge[k].from = s; edge[k].to = e; edge[k].w = w; edge[k].next = Head[s]; Head[s] = k ++; } bool BFS(int s,int e)///从源点到汇点找到一条路径 { memset(vis, false, sizeof(vis)); queue<int> Q; Q.push(s); Pre[s] = -1; vis[s] = true; while( Q.size() ) { int v = Q.front(); Q.pop(); if(v == e) return true; for(int i=Head[v]; i != -1; i = edge[i].next) { int to = edge[i].to; if( !vis[to] && edge[i].w ) { vis[to] = true; Pre[to] = i; Q.push(to); } } } return false; } int Karp(int s,int e) { int ans = 0; while( BFS(s, e) )///如果能找到路径就一直找 { int MinFlow = INF, Cur = Pre[e]; while(Cur != -1) { MinFlow = min(MinFlow, edge[Cur].w); Cur = Pre[edge[Cur].from]; } ans += MinFlow; Cur = Pre[e]; while(Cur != -1) { edge[Cur].w -= MinFlow; edge[Cur^1].w += MinFlow; Cur = Pre[edge[Cur].from]; } } return ans; } int main() { while(cin >> m >> n) { int s, e, w; Init(); for(int i=0; i<m; i++) { scanf("%d %d %d", &s, &e, &w); AddEdge(s, e, w); AddEdge(e, s, 0);///增加的反向边 } printf("%d\n", Karp(1, n) ); } return 0; }
==========================================================================================================
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<queue> using namespace std; typedef long long LL; const LL INF = 1e9+7; const LL maxn = 1005; const LL MOD = 1e9+7; int n, m, Head[maxn], k; int Depth[maxn]; bool vis[maxn]; struct node { int s, e, flow; int next; }edge[maxn*2]; void AddEdge(int s,int e,int flow) { edge[k].s = s; edge[k].e = e; edge[k].flow = flow; edge[k].next = Head[s]; Head[s] = k ++; } bool BfsDepth(int Star,int End) { memset(Depth, 0, sizeof(Depth) ); queue<int> Q; Depth[Star] = 1; Q.push(Star); while( Q.size() ) { int s = Q.front(); Q.pop(); if(s == End) return true; for(int i=Head[s]; i != -1; i=edge[i].next) { int e = edge[i].e; if(!Depth[e] && edge[i].flow) { Q.push(e); Depth[e] = Depth[s] + 1; } } } return false; } int DFS(int s,int MaxFlow)///从s点发出的最大流量是MaxFlow { if(s == n) return MaxFlow; int sFlow = 0;///sFlow 从 for(int i=Head[s]; i != -1; i = edge[i].next) { int e = edge[i].e, flow = edge[i].flow; if(Depth[s]+1 == Depth[e] && flow)///到达下一层 { flow = min(MaxFlow-sFlow, flow); flow = DFS(e, flow); edge[i].flow -= flow; edge[i^1].flow += flow; sFlow += flow; if(sFlow == MaxFlow) break; } } if(sFlow == 0) Depth[s] = 0; return sFlow; } int Dinic(int s,int e) { int ans = 0; while(BfsDepth(s,e) == true) { ans += DFS(s, INF); } return ans; } int main() { while(scanf("%d %d",&m, &n) != EOF) { int s, e, w; memset(Head, -1, sizeof(Head)); k = 0; for(int i=0; i<m; i++) { scanf("%d %d %d", &s, &e, &w); AddEdge(s, e, w); AddEdge(e, s, 0);///添加反向边 } printf("%d\n", Dinic(1, n) ); } return 0; }