日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

最大流EK和Dinic算法

發(fā)布時間:2023/12/2 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 最大流EK和Dinic算法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

最大流EK和Dinic算法

EK算法

最樸素的求最大流的算法。
做法:不停的尋找增廣路,直到找不到為止

代碼如下:

@Frosero #include <cstdio> #include <iostream> #include <cstring> #include <queue> #define INF 0x3f3f3f3fusing namespace std; int n,m; int cap[202][202],flow[202][202],mf[202],pre[202];//cap為網(wǎng)絡(luò)的容量 flow為現(xiàn)在的流量 //mf[i]為原點到點i的最大流量 pre[i]為增廣路上i點上一個點int EK(int s,int t){memset(flow,0,sizeof(flow));queue<int>q;int ans = 0;while(1){while(!q.empty()) q.pop(); q.push(s);memset(mf,0,sizeof(mf));mf[1] = INF;while(!q.empty()){int u = q.front(); q.pop();for(int i=1;i<=m;i++)if(!mf[i] && flow[u][i] < cap[u][i]){pre[i] = u;q.push(i);mf[i] = min(mf[u],cap[u][i] - flow[u][i]);}}if(mf[t] == 0) break;ans += mf[t];for(int i=t;i!=s;i=pre[i]){flow[pre[i]][i] += mf[t];flow[i][pre[i]] -= mf[t];}}return ans; }int main(){while(scanf("%d %d",&n,&m)!=EOF){memset(cap,0,sizeof(cap));memset(flow,0,sizeof(flow));int u,v,w;while(n--){scanf("%d %d %d",&u,&v,&w);cap[u][v] += w;}printf("%d\n",EK(1,m));} }

Dinic算法

Dinic的優(yōu)化部分就是給殘留網(wǎng)絡(luò)生成一個層次圖,然后盡量的利用層次圖后再形成新的層次圖。

理論上Dinic和EK算法的時間復(fù)雜度差不多,但是事實上Dinic算法要好得多。

代碼如下:

@Frosero #include <iostream> #include <cstdio> #include <queue> #include <cstring> #define INF 0x3f3f3f3fusing namespace std;int n,m,flow[202][202],cap[202][202]; int dis[202];//flow為現(xiàn)在的流量 cap為網(wǎng)絡(luò)的容量//dis為點的層次bool bfs(){ //形成層次圖memset(dis,-1,sizeof(dis));dis[1] = 0;queue<int>q; q.push(1);while(!q.empty()){int u = q.front(); q.pop();for(int i=1;i<=m;i++)if(dis[i] == -1 && flow[u][i] < cap[u][i]){dis[i] = dis[u] + 1;q.push(i);}}if(dis[m] == -1) return false;else return true; }int dfs(int s = 1,int f = INF){ //利用層次圖不斷尋找增廣路if(s == m || f == 0) return f;int ans = 0;for(int i=1;i<=m;i++)if(dis[i] == dis[s] + 1){int a = dfs(i,min(f,cap[s][i] - flow[s][i]));if(a == 0) continue;flow[s][i] += a;flow[i][s] -= a;ans += a;f -= a;if(f <= 0) break;}return ans; }int dinic(){ //Dinic主過程int ans = 0;while(bfs()){ans += dfs();}return ans; }int main(){while(scanf("%d %d",&n,&m)!=EOF){ //本代碼假設(shè)1為原點 m為匯點memset(flow,0,sizeof(flow));memset(cap,0,sizeof(cap));int u,v,w;while(n--){scanf("%d %d %d",&u,&v,&w);cap[u][v] += w;}printf("%d\n",dinic());}return 0; }

轉(zhuǎn)載于:https://www.cnblogs.com/ScratchingBear/p/5345837.html

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結(jié)

以上是生活随笔為你收集整理的最大流EK和Dinic算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。