網路流演算法 網路流演算法用於解決從源點到匯點最大流的問題。 edmonds-karp演算法 演算法主要思想: 每次bfs找到一條從源點到匯點的最少路徑數的可行路徑,同時把這條路徑塞滿,這條路上的最小容量即為這條路徑的流量。然後將這條路徑的正向邊刪除,增加一條容量相同的反向邊,當bfs無法進行下去的時候,則演算法結束,最大流為每次bfs找到的可行路徑的流量和。
poj1273 drainage ditches
#include #include #include #include #include using namespace std;
int g[300][300];
bool visited[300];
int prev[300];
int n,m;
int augment()
else
}} }
int nminflow=9999999;
if(!bfindpath)
return 0;
//構建新殘餘網路,構建增廣路徑
v=m;
while(prev[v])
v=m;
while(prev[v])
return nminflow;
}int main()
int nmaxflow=0;
int aug;
while(aug=augment()) //每次通過bfs找到乙個可行路徑
printf("%d\n",nmaxflow);
} return 0;
}
2.dinic演算法
為了少做幾次
bfs。
解決方法:先對結點進行分層,然後以層次數進行
dfs,這樣一次的增廣過程可以通過
dfs找到幾條可行路徑。結點回溯回溯到該路徑的流量對應的最小層數容量邊的起點。同時還要注意要將原圖備份,使用原圖上的邊的容量減去做完最大流的殘餘網路上的邊的剩餘容量,就是邊的容量。
poj 3436 acm computer factory
#include #include #include #include #include #include using namespace std;
#define mymax 120
#define infinite 99999999
int p, n;
int t; //彙總編號
struct machine
machines[100];
int g[mymax][mymax]; // machines[i] 對應於節點 i 和 i + n,兩者之間連邊權為machines[i].q
int g2[mymax][mymax]; // machines[i] 對應於節點 i 和 i + n,兩者之間連邊權為machines[i].q
int maxflow;
bool myequal( int * s1, int * s2,int p)
return true;
}int visited[mymax];
int layer[mymax];
bool countlayer()
} }return false;
}int dinic()
}nmaxflow += nminc;
for( i = 1;i < q.size();i ++ )
while( ! q.empty() && q.back() != nminc_vs)
}else
}if( i > t )
q.pop_back();
}} }
return nmaxflow;
}int main()
t = 2 * n + 1; //匯點編號
//每個機器拆成兩個點 i 和 i + n,乙個用於接收部件,乙個用於產出
//從i 到i + n 連邊,容量 就是 qi
for( i = 1; i <= n ; i ++ )
int k;
g[0][i] = infinite;
for( k = 0; k < p; k ++ )
if( machines[i].in[k] == 1 )
g[i+n][t] = infinite;
for( k = 0; k < p; k ++ )
if( machines[i].out[k] == 0 || machines[i].out[k] == 2 )
} memcpy(g2, g,sizeof(g));
int nmaxflow = dinic();
int nedges = 0;
for( i = n + 1; i < t;i ++ )
for( j = 1; j <= n; j ++ )
if( g[i][j] < g2[i][j] )
nedges ++;
cout << nmaxflow << " " << nedges << endl;
for( i = n + 1; i < t;i ++ )
for( j = 1; j <= n; j ++ )
if( g[i][j] < g2[i][j] )
cout << i - n << " " << j << " " << g2[i][j] - g[i][j] << endl;
return 0;
}
其他典型例題:
poj2112 optimal milking
poj1149 pigs
3. 有流量下界的網路最大流處理方法:
思路:分離下界
新增新的節點x,
y,使得x,
y成為新圖的源點和匯點,若新圖的最大流中,源點
y的所有發出邊全部被覆蓋,則原圖有解,否則無解。這樣就轉換成了普通網路流問題進行解決。
poj2396 budget
4.最小費用最大流
每條邊上多了乙個輸送單位流量的費用引數
,在最大流中尋找乙個費用最小的最大流
.poj 2135
#include #include #include #include #include #include using namespace std;
#define maxn 1000
#define maxm 20000
struct edge
edge[maxm+1];
int father[maxn+1];
int reach[maxn+1];
int cost[maxn+1];
int m,n;
int findpath(int s,int t)}}
else}}
} }if(!reach[t])
return -1;
else
else
}} return cost[t];}
void solve()
m=m+m;
ans=findpath(1,n)+findpath(1,n);
printf("%d\n",ans);
}int main()
網路流演算法
問題描述 如圖4 1所示是聯結某產品地v1和銷售地v4的交通網,每一弧 vi,vj 代表從vi到vj的運輸線,產品經這條弧由vi輸送到vj,弧旁的數表示這條運輸線的最大通過能力。產品經過交通網從v1到v4。現在要求制定乙個運輸方案使從v1到v4的產品數量最多。圖 4 1 圖 4 2 一 基本概念及相...
網路流演算法
ek演算法模板 演算法複雜度 n m m n為點數,m為邊數 源點 1,匯點 n。const int maxn 310,inf 0x7fffffff int pre maxn mat maxn maxn bool vis maxn int n,m int augment else q.push ba...
網路流演算法
看見了一篇非常不錯的博文 1 容量限制 2 流量守恆 3 斜對稱性 x向y流了f的流 y就向x流了 f的流 殘留網路 容量網路 流量網路 這個等式是始終成立的 殘留值當流量值為負時甚至會大於容量值 流量值為什麼會為負?有正必有負,記住斜對稱性 最短路徑增廣演算法 增廣路方法是很多網路流演算法的基礎 ...