// 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;
else
que.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;
}
poj 1273 Drainage Ditches 网络流 Edmond Karp || Dinic
最新推荐文章于 2019-10-31 21:58:36 发布