标签:
题目链接:
http://poj.org/problem?id=1273
题目大意:
农民John的田里有M个池塘和N条水沟用来排水,池塘编号为1~M,1号池塘是所有水沟的源点,
M号池塘是水沟的汇点。给你N条水沟所连接的池塘和所能流过的水量,求整个水沟从源点到汇点
最多能流多少水。
思路:
很明显的求网络流最大流问题。用链式前向星(邻接表)来存储网络,这样就不用考虑重边问题了。这
里的重边其实就是平行边。用SAP算法+GAP优化来求最大流就可以了。SAP+GAP模板参考我的另
一篇博文:http://blog.csdn.net/lianai911/article/details/44962653
AC代码:
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<queue> using namespace std; const int MAXN = 220; const int MAXM = MAXN*MAXN; const int INF = 0xffffff0; struct EdgeNode { int to; int w; int next; }Edges[MAXM]; int Head[MAXN],id; void AddEdges(int u,int v,int w) { Edges[id].to = v; Edges[id].w = w; Edges[id].next = Head[u]; Head[u] = id++; Edges[id].to = u; Edges[id].w = 0; Edges[id].next = Head[v]; Head[v] = id++; } int Numh[MAXN],h[MAXN],curedges[MAXN],pre[MAXN]; void BFS(int end,int N) { memset(Numh,0,sizeof(Numh)); for(int i = 1; i <= N; ++i) Numh[h[i]=N]++; h[end] = 0; Numh[N]--; Numh[0]++; queue<int> Q; Q.push(end); while(!Q.empty()) { int v = Q.front(); Q.pop(); int i = Head[v]; while(i != -1) { int u = Edges[i].to; if(h[u] < N) { i = Edges[i].next; continue; } h[u] = h[v] + 1; Numh[N]--; Numh[h[u]]++; Q.push(u); i = Edges[i].next; } } } int SAP(int start,int end,int N) { int Curflow,FlowAns = 0,temp,neck; memset(h,0,sizeof(h)); memset(pre,-1,sizeof(pre)); for(int i = 1; i <= N; ++i) curedges[i] = Head[i]; BFS(end,N); int u = start; while(h[start] < N) { if(u == end) { Curflow = INF; for(int i = start; i != end; i = Edges[curedges[i]].to) { if(Curflow > Edges[curedges[i]].w) { neck = i; Curflow = Edges[curedges[i]].w; } } for(int i = start; i != end; i = Edges[curedges[i]].to) { temp = curedges[i]; Edges[temp].w -= Curflow; Edges[temp^1].w += Curflow; } FlowAns += Curflow; u = neck; } int i; for(i = curedges[u]; i != -1; i = Edges[i].next) if(Edges[i].w && h[u]==h[Edges[i].to]+1) break; if(i != -1) { curedges[u] = i; pre[Edges[i].to] = u; u = Edges[i].to; } else { if(0 == --Numh[h[u]]) break; curedges[u] = Head[u]; for(temp = N,i = Head[u]; i != -1; i = Edges[i].next) if(Edges[i].w) temp = min(temp,h[Edges[i].to]); h[u] = temp + 1; ++Numh[h[u]]; if(u != start) u = pre[u]; } } return FlowAns; } int main() { int N,M,u,v,w; while(~scanf("%d%d",&N,&M)) { memset(Head,-1,sizeof(Head)); id = 0; for(int i = 0; i < N; ++i) { scanf("%d%d%d",&u,&v,&w); AddEdges(u,v,w); } printf("%d\n",SAP(1,M,M)); } return 0; }
POJ1273 Drainage Ditches【最大流】【SAP】
标签:
原文地址:http://blog.csdn.net/lianai911/article/details/44964361