網路流 加上了當前弧優化的Dinic演算法

2021-09-25 22:15:20 字數 2312 閱讀 6549

測試題目:

題目背景

滾粗了的hansbug在收拾舊語文書,然而他發現了什麼奇妙的東西。

題目描述

蒟蒻hansbug在一本語文書裡面發現了一本答案,然而他卻明明記得這書應該還包含乙份練習題。然而出現在他眼前的書多得數不勝數,其中有書,有答案,有練習冊。已知乙個完整的書冊均應該包含且僅包含一本書、一本練習冊和乙份答案,然而現在全都亂做了一團。許多書上面的字跡都已經模糊了,然而hansbug還是可以大致判斷這是一本書還是練習冊或答案,並且能夠大致知道一本書和答案以及一本書和練習冊的對應關係(即僅僅知道某書和某答案、某書和某練習冊有可能相對應,除此以外的均不可能對應)。既然如此,hansbug想知道在這樣的情況下,最多可能同時組合成多少個完整的書冊。

輸入格式

第一行包含三個正整數n1、n2、n3,分別表示書的個數、練習冊的個數和答案的個數。

第二行包含乙個正整數m1,表示書和練習冊可能的對應關係個數。

接下來m1行每行包含兩個正整數x、y,表示第x本書和第y本練習冊可能對應。(1<=x<=n1,1<=y<=n2)

第m1+3行包含乙個正整數m2,表述書和答案可能的對應關係個數。

接下來m2行每行包含兩個正整數x、y,表示第x本書和第y本答案可能對應。(1<=x<=n1,1<=y<=n3)

輸出格式

輸出包含乙個正整數,表示最多可能組成完整書冊的數目。

輸入輸出樣例

輸入 #1 複製

5 3 4

54 3

2 25 2

5 15 3

51 3

3 12 2

3 34 3

輸出 #1 複製

2說明/提示

樣例說明:

如題,n1=5,n2=3,n3=4,表示書有5本、練習冊有3本、答案有4本。

m1=5,表示書和練習冊共有5個可能的對應關係,分別為:書4和練習冊3、書2和練習冊2、書5和練習冊2、書5和練習冊1以及書5和練習冊3。

m2=5,表示數和答案共有5個可能的對應關係,分別為:書1和答案3、書3和答案1、書2和答案2、書3和答案3以及書4和答案3。

所以,以上情況的話最多可以同時配成兩個書冊,分別為:書2+練習冊2+答案2、書4+練習冊3+答案3。

資料規模:

對於資料點1, 2, 3,m1,m2<= 20

對於資料點4~10,m1,m2 <= 20000

原理:現在的**相對於以前就多了乙個now陣列;now陣列運用在dinic演算法的dfs部分,以前我們每次總是從乙個點的第一條邊開始進行,但是因為我們如果得到了一次答案那麼這次答案的路徑一永遠不會再次去跑一邊的,now陣列去記錄了每次跑完之後的的當前的邊,使得當我們的dfs回溯到乙個跑過一次的點之後可以直接從now陣列記錄的邊開始跑dfs。每次的bfs跑完之後需要初始化一次now陣列。

我的** 在這道題目從 2.2s左右 優化到了 660ms左右 。

ac**:

#include #include #include #include using namespace std;

const int n = 4e4 + 5, m = 2e5;

const int inf = 0x3f3f3f3f;

int n1, n2, n3, m1, m2, s, t, maxflow;

int h[n], w[m], e[m], ne[m], idx;

int d[n];

int now[m];

inline void add(int a, int b, int c)

inline bool bfs(void)

} }return d[t] != 0;

}inline int dinic(int u, int flow) else d[v] = 0;

} now[u] = i; }

return 0;

}int main(void)

//書連書

for(int i = 1; i <= n1; i ++)

add(n2 + i, n2 + n1 + i, 1);

//書連答案

scanf("%d", &m2);

for(int i = 1; i <= m2; i ++)

//答案連匯點

for(int i = 1; i <= n3; i ++)

add(n2 + 2 * n1 + i, t, 1);

int flow;

while(bfs())

printf("%d\n", maxflow);

// fclose(stdin);

return 0;

}

網路流 最大流 dinic 當前弧優化 模板

用法 在原有向圖的基礎上,增加源點s和匯點t,並將s與左子集建邊,t與右子集建邊 邊權都設為1,則就是求二分圖最大匹配 右子集與t的邊權大於1,則就是求二分圖最大多重匹配 模板 const int n 210 struct edge edge n n 邊數 int head n cnt void a...

網路最大流 附當前弧優化

一篇巨佬的網路流建模 網路最大流問題就是給你乙個有向圖,告訴你乙個源點與乙個匯點,並給每一條邊乙個最大流量,需要你求出從源點最多能夠發出多少單位流量到匯點 哎呀我也說不清,就是給你一些或大或小的管道 每個管道都有最大秒流量 一些中轉站,一座供水塔以inf單位每秒的速度供水,問你家每秒最多得到多少單位...

網路流的部分優化

只是幫助自己記憶一下。isap應該是一種複雜度比較優秀的最大流演算法。具體優化分為兩部分,都是基於dinic之上的。1.1.1.當前弧優化,這種優化比較顯然,就是對於每一次流,每條邊一定是只經過一次的,那麼這樣就可以將每條流過的變在鏈式前向星中刪掉。2.2.2.高階版分層圖優化。這個現在不是很理解。...