網路流ek演算法資料結構:佇列
主要操作:廣搜 記錄路徑 更新
能解決的問題:最大流(最小割)
複雜度:o(mv)v指最大容量,m指邊數。
新名詞:
1.增廣路:從源點source到tink的一條簡單路,如果路上的每條邊(u,v)的可改進量均大於0,則稱這條路為一條增廣路。
增廣路定理:網路達到最大流量當且僅當不存在增廣路。
增廣路演算法:從乙個可行流開始不斷的尋找可增廣路,然後沿著它增廣,直到它不存在。
2.反向弧:如果有一條弧(u,v),那麼再進行網路流演算法時,要對它建立反向弧(v,u),反向弧的容量為0,與正向弧相反,正向弧減少容量時,反向弧增加容量。建立反向弧能更多的增廣,使網路流演算法正確。(無法給出證明)
3.可行弧:在ek演算法中指可從u到v增加流量(也就是容量不為0)。
4.可行路:從源點source到tink的有可行弧構成的路徑叫做可行路。
具體操作:
1.建立網路(正向弧+反向弧)
2.從源點出發,廣搜一條最短可行路(即最先到達匯點tink的那條路),每次到達乙個點用pre陣列記錄是由那條邊過來的(為後面減小流量做準備)
3.到達匯點tink時,按照pre陣列記錄的,從可行路中找一條容量最小的進行容量減少。即找到了一條割邊。
4.重複操作2.3
,直到無法到達匯點,演算法結束,即找到了最大流,演算法結束。
4.2.1 純網路流演算法,可用來試ek的正確性,但ek只能拿50分!
1 #include2 #include3 #include4 #include5using
namespace
std;67
#define inf 1000000 89
struct
edge10;
1314 edge map[200
];15
int que[20000
];16
bool b[500];//
用b陣列記錄是否入隊,可以防止重複入隊,因為有反向弧和環!!
17int
source,tink,n,m,tot,ans,head,tail;
18int first[500
];19
int pre[500
];20
21int fmin(int x ,int
y)22
2627
void build(int x ,int y ,int
c)28
4445
void
init()
4656 source=n+1; tink=n+2;//
手動建立源點和匯點,看題目要求!
57 build(source,1
,inf);
58build(n,tink,inf);59}
6061
bool
bfs()
6280 t=map[t].next;81}
82 head++;
83 b[x]=false;84
}
85return
false;86
}8788void
updata()
8995
for (int p=pre[tink];p!=-1;p=pre[map[p].x])//
更新容量過程
96100 ans+=min;
101}
102103
void
ek()
104110 printf("
%d\n
",ans);
111}
112113
intmain()
114
網路流演算法
問題描述 如圖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無法進行下去的時候...