P3376 模板 網路最大流

2022-05-16 07:41:05 字數 2409 閱讀 3377

luogu p3376

求網路最大流.

首先介紹一下網路流的基本概念. 乙個帶權有向圖, 邊權稱為容量. 其中乙個只有出度的點, 源點, 乙個只有入度的點, 匯點.

流從源點源源不斷地產生, 在匯點消失. 邊的容量就是能它流過的最大流, 實際流過的流成為邊的流量. 源點流出的最大的流一定和匯點消失的最大的流相等, 我們把這個最大流稱為這個網路的流.

有流流過網路時, 邊的剩餘剩餘流量構成的網路, 稱殘量網路.

一條邊本沒有反向容量, 但是由於有流正向流過時, 相當於給這條邊減少了反向流量. 反向流量為負數, 反向容量為 \(0\), 所以就出現了反向餘量.

為了記錄反向流量, 我們給每一條邊另開一條反向的容量為 \(0\) 的邊, 以完整儲存殘量網路.

殘量網路裡, 一條從源點通往匯點的路徑, 稱為增廣路, 即可以增加當前網路流量的路徑. 只要找到一條增廣路, 就可以更新殘量網路.

基於 bfs 的演算法, 一次bfs可找到一條長度最小 (經過邊最少) 的增廣路, 更新答案, 並且每次記錄增廣路, 從匯點反向回溯到源點, 更新殘量網路. 當殘量網路中源點到匯點不連通時, 說明已經沒有增廣路可找了, 演算法結束.

dfs 和 bfs 結合, 每輪可找多條增廣路. 用 dfs 搜尋時, 會嘗試將流入乙個節點的流全部流出. 但是只有 dfs 會導致在正反向邊反覆流. 所以用 bfs 給殘量網路分層, 每次只能順著分層圖走, 防止回頭.

兩種演算法的框架相似, 所以部分可能會合併.

本題規模可以允許鄰接矩陣去重邊, 提高演算法主體效率.

void lnk(node *x /*起點*/, node *y /*終點*/, const long long &z /*容量*/) 

x->fst[y - n] = cnte; //新邊(記憶體池中取用)

cnte->to = y; //終點

cnte->mx = z; //容量

(cnte++)->nw = 0; //流量為零

return;

}

int main() 

for (register unsigned int i(1); i <= n; ++i)

}} edmonds_karp/dinic();//演算法主體

printf("%llu\n", ans);

return 0;

}

演算法主體, 負責呼叫fnd(找增廣路),bk(更新殘量網路) 和初始化

void edmonds_karp()  else 

} return;

}

這是edmonds-karp的一部分, 採用 bfs 的方式, 找到就返回.

void fnd() }}

} return;

}

順著之前記錄的前驅組成的鏈往回走, 借助鄰接矩陣更新邊流量.

void bk() 

return;

}

沒什麼新東西, 只是在edmonds-karp的基礎上變了變形. 操作都封裝在bfsdfs裡了.

void dinic() 

ans += dfs(s,

0x3f3f3f3f3f3f3f3f); //流入源點無限流,

//函式返回找到的所有增廣路流的和, 計入答案

} return;

}

edmonds-karpfnd簡單了一些, 需要注意的是這個 bfs 搜到匯點不返回, 因為在 dfs 中, 為了優化效率, 無論什麼深度的點, 都可以直接通往匯點, 所以搜尋標記深度比匯點大的點.

void bfs() 

}} return;

}

這是 dinic 的核心, 摒棄了之前 bfs 最後更新殘量網路的做法, 因為 dfs 的回溯時更新時很方便的.

long long dfs(node *x, long long cm /*嘗試流入當前點的流*/) 

if (x->scd[i]->mx > x->scd[i]->nw &&

dep[x->scd[i]->to - n] ==

dep[x - n] + 1)

tmp = min(x->scd[i]->mx - x->scd[i]->nw, cm); //可流入目標點的流量

if (tmp = dfs(x->scd[i]->to, tmp))

}} return sum;

}

P3376 模板 網路最大流

網路流用於解決流量問題 網路流 所有弧上流量的集合f 稱為該容量網路的乙個網路流。1 定義 帶權的有向圖g v,e 滿足以下條件,則稱為網路流圖 flow network 僅有乙個入度為0的頂點s,稱s為源點。僅有乙個出度為0的頂點t,稱t為匯點。每條邊的權值都為非負數,稱為該邊的容量,記作c i,...

P3376 模板 網路最大流

ek演算法 個人感覺沒有dinic好理解 1 edmonds karp演算法2 時間複雜度o n m m 3 include4 include5 include6 include7 include8 using namespace std 910 const int n 10005 11 const...

P3376 模板 網路最大流

如題,給出乙個網路圖,以及其源點和匯點,求出其網路最大流。輸入格式 第一行包含四個正整數n m s t,分別表示點的個數 有向邊的個數 源點序號 匯點序號。接下來m行每行包含三個正整數ui vi wi,表示第i條有向邊從ui出發,到達vi,邊權為wi 即該邊最大流量為wi 輸出格式 一行,包含乙個正...