看見了一篇非常不錯的博文
1 容量限制
2 流量守恆
3 斜對稱性 x向y流了f的流 y就向x流了-f的流
殘留網路 = 容量網路 - 流量網路
這個等式是始終成立的 殘留值當流量值為負時甚至會大於容量值
流量值為什麼會為負?有正必有負,記住斜對稱性!
最短路徑增廣演算法
增廣路方法是很多網路流演算法的基礎 一般都在殘留網路中實現
其思路是每次找出一條從源到匯的能夠增加流的路徑 調整流值和殘留網路 不斷調整直到沒有增廣路為止
ff方法的基礎是增廣路定理: 網路達到最大流當且僅當殘留網路中沒有增廣路
ek演算法就是不斷的找最短路 找的方法就是每次找一條邊數最少的增廣 也就是最短路徑增廣
2.如何找到一條增廣路?
先明確什麼是增廣路 增廣路是這樣一條從s到t的路徑 路徑上每條邊殘留容量都為正
把殘留容量為正的邊設為可行的邊 那麼我們就可以用簡單的bfs得到邊數最少的增廣路
3.如何增廣?
bfs得到增廣路之後 這條增廣路能夠增廣的流值 是路徑上最小殘留容量邊決定的
把這個最小殘留容量mincap值加到最大流值flow上 同時路徑上每條邊的殘留容量值減去mincap
最後 路徑上每條邊的反向邊殘留容量值要加上mincap
上面還遺留了乙個反向邊的問題: 為什麼增廣路徑上每條邊的反向邊殘留容量值要加上mincap?
因為斜對稱性! 由於殘留網路=容量網路-流量網路
容量網路不改變的情況下
由於增廣好比給增廣路上通了一條流 路徑說所有邊流量加mincap
流量網路中路徑上邊的流量加mincap 反向邊流量減去mincap
相對應的殘留網路就發生相反的改變
這樣我們就完成了ek演算法 具體實現可以用鄰接表存圖 也可以用鄰接矩陣存圖
鄰接表存圖 由於流量同時存在於邊與反向邊 為了方便求取反向邊 建圖把一對互為反向邊的邊建在一起
1.任意乙個流都小於等於任意乙個割
2.構造出乙個流等於乙個割
3.最大流等於最小割
struct edge
};int n, m;//n為點數,m為邊數
vectore;//儲存所有邊的資訊
vectorg[maxn];//鄰接表,g[i][j]儲存節點i的第j條邊在e陣列裡面的編號
int a[maxn];//每個點目前流經的水量
int p[maxn];//p[i]從原點s到終點t的節點i的前一條邊的編號
void init(int n)
void addedge(int u, int v, int c)
int maxflow(int s, int t)//起點為s,終點為t
}if(a[t])break;//如果已經流到了終點t,退出本次找增廣路
}if(!a[t])break;//如果所有路都已經試過,水不能流到終點,說明已經沒有增廣路,已經是最大流
for(int u = t; u != s; u = e[p[u]].from)//反向記錄路徑
flow += a[t];//最大流加上本次流到終點的流量
}return flow;
}
poj 1273
#include#include#include#include#include#include#include#includeusing namespace std;
const int inf = 1e9 + 10;
int n,m,x,y,z,ans,l,r,minn;
int g[500][500];
int q[500],pre[500];
bool p[500],flag;
int main()
ans = 0;
while(1)
}if(flag) break;
l++;
}if(!flag) break;
minn = inf;
for(int i = r; q[i] != 1; i = pre[i])
minn = min(minn,g[q[pre[i]]][q[i]]);
for(int i = r; q[i] != 1; i = pre[i])
ans += minn;
}printf("%d\n",ans);
}return 0;
}
網路流演算法
問題描述 如圖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...
網路流演算法
網路流演算法 網路流演算法用於解決從源點到匯點最大流的問題。edmonds karp演算法 演算法主要思想 每次bfs找到一條從源點到匯點的最少路徑數的可行路徑,同時把這條路徑塞滿,這條路上的最小容量即為這條路徑的流量。然後將這條路徑的正向邊刪除,增加一條容量相同的反向邊,當bfs無法進行下去的時候...