網路最大流之一般增廣路方法——Ford-Fulkerson

來源:互聯網
上載者:User

      在該演算法中,尋找增廣路和改進網路流的方法稱為標記法。

       對於標記的過程不多加闡述,以下對標記的程式實現做下小小總結:

1:在程式中需要定義三個陣列變數分別是flag[],prev[],alpha[],其中:

 flag[]表示頂點的狀態,其元素取值及其含義為:-1表示未標號,0表示已標號未檢查,1表示已標號已檢查

 prev[]為標號的第一個分量:指明標號是從哪一個頂點那裡得到的,以便找出可改進量

 alpha[]為標號的第二個分量,用以確定增廣路的可改進量

2:每一次的標號過程如下

(1)先將flag,prev,alpha這3個數組初始化為-1

(2)將源點初始化為已標號未檢查的頂點,即flag[0]=0,prev[0]=0,alpha[0]=INF,INF表示為無窮大;並將源點入隊列

(3)當隊列非空並且匯點沒有標號的時候,從隊列頭取出隊列的頭頂點,設這個頂點為v,v肯定為已標號未檢查的頂點;因此,檢查頂點v的正向和反向的“鄰接”頂點,如果沒有標號當前可以進行標號,則對這些頂點進行標號併入隊,這些頂點都是已標號未檢查的頂點,此後頂點v為已標號已檢查的頂點了。反覆執行這一步直到隊列為空白或者匯點已獲得標號

3:

標號完畢後,要進行調整,調整方法是:從匯點出發,通過標號的第一個分量採用“倒向追蹤”的方法,一直找到源點為止,這個過程途徑頂點和弧就構成了增廣路。可改進量為匯點的第二個分量

 

參考模版:

#include<stdio.h>#include<string.h>#include<math.h>#define MAX 1000#define INF 100000#define MIN(a,b) ((a)<(b) ? (a):(b))struct map//弧結構{int c,f;//容量,流量}edge[MAX][MAX];int m,n;//弧數 頂點數int flag[MAX]; //頂點的狀態,-1未標號,0已標號未檢查,1已標號已檢查int pre[MAX]; //標號的第一個分量:指明標號從哪個頂點得到,以便找出改進量int alpha[MAX]; //標號的第二個分量,可改進量βint queue[MAX]; //類比隊列int qs,qe; //隊列頭和隊列尾位置int v; //從隊列裡取出來的隊頭元素int i,j;//尋找增廣路void BFS(){memset(flag, 0xff, sizeof(flag)); //初始化為-1memset(pre, 0xff, sizeof(pre));memset(alpha, 0xff, sizeof(alpha));flag[0] = 0; //源點初始化,已標號未檢查pre[0] = 0;alpha[0] = INF;qs = qe = 0;queue[qe] = 0; //源點入隊列qe++;while(qs<qe && flag[n-1]==-1){v= queue[qs]; //取出隊列頭頂點qs++;for(i=0; i<n; i++)//檢查頂點v的正向和反向鄰接點{ if(flag[i] == -1)//頂點未標號{ if(edge[v][i].c<INF && edge[v][i].f<edge[v][i].c)//正向且未滿{ flag[i] = 0; //給頂點i標號(已標號未檢查)pre[i] = v;alpha[i] = MIN(alpha[v],edge[v][i].c-edge[v][i].f);queue[qe] = i; //頂點i入隊列qe ++;}else if(edge[i][v].c<INF && edge[i][v].f>0) //反向且有流量{flag[i] = 0; //給頂點i標號(已標號未檢查)pre[i] = -v;alpha[i] = MIN(alpha[v], edge[i][v].f);queue[qe] = i; //頂點i入隊列qe ++;}}}flag[v] = 1; //頂點i已標號已檢查}}//Ford_Fulkerson演算法void Ford_Fulkerson(){ while(1){BFS();if( alpha[n-1]==0 || flag[n-1]==-1 ) //當匯點沒有獲得標號,或者匯點調整量為0, 應該退出迴圈break;//當匯點有標號,應該進行調整int k1=n-1, k2=abs( pre[k1] );int a = alpha[n-1]; //可改進量while(1){if(edge[k2][k1].f <INF) //正向edge[k2][k1].f = edge[k2][k1].f + a;else //反向edge[k1][k2].f = edge[k1][k2].f - a;if(k2 == 0) //調整一直到源點v0break;k1 = k2;k2 = abs( pre[k2] );}alpha[n-1] = 0;}}//求最大流void Max_flow(){int maxflow = 0;for(i=0; i<n; i++){for(j=0; j<n; j++){if(i==0 && edge[i][j].f<INF)//求源點的流出量  即最大流maxflow += edge[i][j].f;if(edge[i][j].f < INF)printf("%d->%d:%d\n",i,j,edge[i][j].f);}}printf("maxflow: %d\n",maxflow);}int main(){int u,v,c,f;scanf("%d%d",&n,&m);for(i=0; i<n; i++)for(j=0; j<n; j++)edge[i][j].c = edge[i][j].f = INF;for(i=0; i<m; i++) //讀入每條弧{scanf("%d%d%d%d",&u,&v,&c,&f);edge[u][v].c = c; //構造鄰接矩陣edge[u][v].f = f;}Ford_Fulkerson();Max_flow();return 0;}

 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.