網路最大流求解 增廣路演算法

2021-06-29 15:59:06 字數 4433 閱讀 7093

增廣路演算法:

根據增廣路地理,為了得到最大流,可以從任何乙個可行流開始,沿著增廣路對網路流進行增廣,直到網路中不存在增廣路為止,這樣的演算法稱為增廣路演算法。

增廣路演算法流程如下。

(1)取乙個可行流f作為初始流(如果沒有給定可行流,則取零流作為初始流)。

(2)尋找關於f的增廣路p,如果找到,則沿著這條增廣路p將f改進成乙個更大的流。

(3)重複 第(2)步直到找不到增廣路為止。

增廣路演算法的關鍵是尋找增廣路和改進網路流。

主要有三種增廣路演算法。(1)ford_fulkerson演算法。(2)最短增廣路演算法。(3)dinic演算法(連續增廣路演算法)。後兩種演算法效率更高。

ford_fulkerson演算法:

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

typedef long long ll;

typedef unsigned long long ull;

const int maxn = 1000;

const int inf = 10000000;

struct arc

;int n,m;

arc edge[maxn][maxn];

int flag[maxn]; //頂點狀態 -1為標號 0已標號未檢查 1已標號已檢查

int prev[maxn]; //標號的第1個分量

int al[maxn]; //標號的第2個分量

void printflow()

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

}void input()

for(int i = 0; i < m; i++) }

void ford_fulkerson()

//反向且有流量

else if(edge[i][v].c != inf && edge[i][v].f > 0)

}flag[v] = 1;//該頂點已檢查

}}//end of while

//匯點未標號或者調整量為0

if(flag[n-1] == -1 || al[n-1] == 0) break;

int p1 = n-1,p2 = abs(prev[p1]);

int a = al[n-1];

while(1)

; }//end of while(1)

//最大流

printflow();

}//end of ford

int main()

/* input:

6 10

0 1 8 2

0 2 4 3

1 3 2 2

1 4 2 2

2 1 4 2

2 3 1 1

2 4 4 0

3 4 6 0

3 5 9 3

4 5 7 2

output:

0->1:2

0->2:3

1->3:2

1->4:2

2->1:2

2->3:1

2->4:0

3->4:0

3->5:3

4->5:2

maxflow:5

0->1:4

0->2:4

1->3:2

1->4:2

2->1:0

2->3:1

2->4:3

3->4:0

3->5:3

4->5:5

maxflow:8

*/

下面兩個是兩個改版ford_fulkerson演算法,分別用dfs和bfs來尋找增廣路:

bfs:

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

const int maxn = 1005;

const int inf = 100000;

struct arc

;int n,m;

arc edge[maxn][maxn];

int vis[maxn];

int a[maxn];

int p[maxn];

void input()

} for(int i = 0; i < m; i++) }

//尋找增廣路

int bfs()

//反向且有流量

else if(edge[i][u].c != inf && edge[i][u].f > 0)}}

vis[u] = 1;

if(vis[n-1]) break;

} if(!vis[n-1]) return 0;

//增廣

int t = n-1;

int alpha = a[n-1];

while(t != 0)

else

t = abs(p[t]);

} return a[n-1];

}void printflow()

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

} int main()

/*

input:

6 10

0 1 8 2

0 2 4 3

1 3 2 2

1 4 2 2

2 1 4 2

2 3 1 1

2 4 4 0

3 4 6 0

3 5 9 3

4 5 7 2

output:

0->1:2

0->2:3

1->3:2

1->4:2

2->1:2

2->3:1

2->4:0

3->4:0

3->5:3

4->5:2

maxflow:5

0->1:4

0->2:4

1->3:2

1->4:2

2->1:0

2->3:1

2->4:3

3->4:0

3->5:3

4->5:5

maxflow:8

*/

dfs:

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

const int maxn = 1005;

const int inf = 100000;

struct arc

;int n,m;

arc edge[maxn][maxn];

int vis[maxn];

void input()

} for(int i = 0; i < m; i++) }

int dfs(int u, int alpha)

//反向且有流量

else if(edge[i][u].c != inf && edge[i][u].f > 0)

}} return 0;

}void printflow()

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

} int main()

printflow();

return 0;

}/*

input:

6 10

0 1 8 2

0 2 4 3

1 3 2 2

1 4 2 2

2 1 4 2

2 3 1 1

2 4 4 0

3 4 6 0

3 5 9 3

4 5 7 2

output:

0->1:2

0->2:3

1->3:2

1->4:2

2->1:2

2->3:1

2->4:0

3->4:0

3->5:3

4->5:2

maxflow:5

0->1:4

0->2:4

1->3:2

1->4:2

2->1:0

2->3:1

2->4:3

3->4:0

3->5:3

4->5:5

maxflow:8

*/

最大流的增廣路演算法

模板題目鏈結 洛谷p3376 模板來自演算法競賽入門經典 第2版 劉汝佳 include using namespace std define inf 0x3f3f3f3f typedef long long ll const int maxn 100010 struct edge 記錄這條邊的資訊...

增廣路徑求解最大流

關於什麼是最大流。我說不清楚,而且也沒有別人的比喻生動。主要是我懶,不想畫圖 演算法的核心在於 找到增廣路徑,修改它,繼續找,直到沒有。while findaugmentpath 判斷是否有增廣路 maxflow maxflow delta 最大流增加 modifygraph 對增廣路進行修改 en...

最大流 增廣路演算法 最小費用最大流

cap flow代表連通,cap flow代表不連通 最大流 不停的尋找s連通至t的路徑,更新.直到找不到路徑 注 p u 1和p u 互為方向邊 include include include include include using namespace std const int maxn 1...