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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

图论 —— 网络流 —— 费用流 —— MCMF 算法

發布時間:2025/3/17 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 图论 —— 网络流 —— 费用流 —— MCMF 算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【概述】

EK 算法是每次用廣搜尋找一條最短的增廣路,然后沿其增廣,而 MCMF 算法是在 EK 算法的基礎上,每次用 SPFA 計算圖的距離標號,然后沿著可行邊進行增廣,即將 EK 算法中的 bfs 替換為 SPFA 求最短路,邊權為該邊的單位流量花費,即改變遍歷的優先級來實現。

【基本思想】

1.每次查找是否存在從源點到匯點可增廣的路徑(源點到匯點的最短路且路徑上的所有邊均不能滿流),并用 pre[i] 記錄路徑上到達點 i 的邊的編號。

2.若存在這樣的路徑,則從匯點沿著 pre 數組向前找,找到該路徑上可以增廣的流量 Min(所有邊中剩余流量最小的),再從匯點遍歷一次,正向邊增加流量 Min,反向邊減少 Min,總費用累加 Min * edge[i].cost,總流量累加 Min

【實現】

struct Edge{int from,to;int cap,flow;int cost;//費用int next;//指向下一條邊的編號 }edge[N]; int head[N],tot; int dis[N];//單源最短路徑 bool vis[N];//SPFA中用于判斷是否在隊列 int pre[N];//記錄從S到i的最小費用路徑上的最后一條弧編號 void addEdge(int x,int y,int cap,int cost){edge[tot].from=x;edge[tot].to=y;edge[tot].cap=cap;edge[tot].flow=0;edge[tot].cost=cost;edge[tot].next=head[x];head[x]=tot++;edge[tot].from=y;edge[tot].to=x;edge[tot].cap=0;edge[tot].flow=0;edge[tot].cost=-cost;edge[tot].next=head[y];head[y]=tot++; } bool SPFA(int S,int T) {queue<int> Q;memset(dis,INF,sizeof(dis));memset(vis,false,sizeof(vis));memset(pre,-1,sizeof(pre));dis[S]=0;Q.push(S);while(!Q.empty()) {int x=Q.front();Q.pop();vis[x]=false;for(int i=head[x];i!=-1;i=edge[i].next) {int y=edge[i].to;int cost=edge[i].cost;int cap=edge[i].cap;int flow=edge[i].flow;if(dis[y]>dis[x]+cost&&cap>flow) {dis[y]=dis[x]+cost;pre[y]=i;if(!vis[y]){vis[y]=true;Q.push(y);}}}}return pre[T]!=-1; } void MCMF(int S,int T,int &flow,int &cost){while(SPFA(S,T)){//每次尋找花銷最小的路徑int minn=INF;for(int i=pre[T];i!=-1;i=pre[edge[i^1].to])//尋找最小增廣流minn=min(minn,edge[i].cap-edge[i].flow);for(int i=pre[T];i!=-1;i=pre[edge[i^1].to]) {edge[i].flow+=minn;edge[i^1].flow-=minn;cost+=edge[i].cost*minn;//增廣流的花銷}flow+=minn;//總流量增加} } int main(){int n,m;scanf("%d%d",&n,&m);tot=0;memset(head,-1,sizeof(head));for(int i=1;i<=n;i++){int x,y,cap,cost;scanf("%d%d%d%d",&x,&y,&cap,&cost);addEdge(x,y,cap,cost);//正向邊}int cost=0,flow=0;//最小費用、最大流int S=1,T=n;//源點與匯點MCMF(S,T,flow,cost);printf("minCost:%d\n",cost);printf("maxFlow:%d\n",flow);return 0; }

?

總結

以上是生活随笔為你收集整理的图论 —— 网络流 —— 费用流 —— MCMF 算法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。