poj 1273 Drainage Ditches 网络流 Edmond Karp || Dinic

来源:互联网 发布:辐射4优化差 编辑:程序博客网 时间:2024/06/06 21:34
// poj 1273 Drainage Ditches 网络流 Edmond Karp || Dinic// 题意: 裸的网络流,点数200,边数200// 解答:经典的ff算法由于效率受容量限制,对于此题,容量可能大于10000000,// 所以采用EK算法,EK的效率是n*m*m,对于此题,可以在时限内解答.// Ford-Fulkerson:由残余网络出发,每次寻找流量的增广路径,每次,至少// 流量至少增加1,每次dfs过程复杂度为m + n,所以复杂度为// 最大流量 * (点数 + 边数)// Edmond-Karp: 每次增广的时候,选择从源到汇,具有最少边数的增广路径.// Dinic: 改进EK,在一次bfs过程中找到多条增广路径,将图进行分层,只要// 图能分层能从源点到达汇点,我们就能找到增广路径.bfs后维护增广// 路径,这里,找到栈中的最小容量的边,以此为起点,进行相应的回溯操作#include <cstdio>#include <cstring>#include <queue>#include <algorithm>using namespace std;const int MAXN = 230;int g[MAXN][MAXN];int vis[MAXN];int pre[MAXN];int n,m;int getPath(){queue<int> que;memset(vis,0,sizeof(vis));memset(pre,0,sizeof(pre));vis[1] = 1;que.push(1);bool flag = 0;while(!que.empty()){if (flag) break;int v = que.front();que.pop();for (int i = 1;i <= n;i ++){if (g[v][i] > 0 && !vis[i]){pre[i] = v;vis[i] = 1;if (i == n){flag = true;break;}else {que.push(i);}}}}if (!flag)return 0;int maxflow = 20000000;int v = n;while(pre[v]){maxflow = min(maxflow,g[pre[v]][v]);v = pre[v];}v = n;while(pre[v]){g[pre[v]][v] -= maxflow;g[v][pre[v]] += maxflow;v = pre[v];}return maxflow;}int layer[MAXN];bool getLayer(){queue<int> que;que.push(1);memset(layer,-1,sizeof(layer));layer[1] = 0;while(!que.empty()){int v = que.front();que.pop();for (int i = 1;i <= n;i ++){if (g[v][i] > 0 && layer[i] == -1){layer[i] = layer[v] + 1;if (i == n)return true;elseque.push(i);}}}return false;}int Dinic(){deque<int> st;int ans = 0;while(getLayer()){st.push_back(1);memset(vis,0,sizeof(vis));vis[1] = 1;while(!st.empty()){int v = st.back();if (v == n){int mi = 20000000;int mi_v ;for (int i = 1;i < st.size();i ++){int s = st[i-1];int e = st[i];if (g[s][e] > 0){if (mi > g[s][e]){mi = g[s][e];mi_v = s;}}}ans += mi;for (int i = 1;i < st.size();i ++){int s = st[i-1];int e = st[i];g[s][e] -= mi;g[e][s] += mi;}while(!st.empty() && st.back()!= mi_v){vis[st.back()] = 0;st.pop_back();}}else {int i;for (i = 1;i <= n;i ++){if (g[v][i] > 0 && layer[i] == layer[v] + 1&& !vis[i]){st.push_back(i);vis[i] = 1;break;}}if (i > n)st.pop_back();}}} return ans;}int EK(){int flow = 0;int ans = 0;while(flow = getPath()){ans += flow;}return ans;}int main(){//freopen("1.txt","r",stdin);while(scanf("%d%d",&m,&n)!=EOF){memset(g,0,sizeof(g));int u,v,c;for (int i = 1;i <= m;i ++){scanf("%d%d%d",&u,&v,&c);g[u][v] += c;}printf("%d\n",EK());printf("%d\n",Dinic());}return 0;}

阅读全文
0 0
原创粉丝点击