網絡流_spfa最小費用最大流

最大流:node

  不斷搜索增廣路,尋找最小的容量-流量,獲得最大流量,但最大流量在有花費時不必定是最小花費。ios

 

最小費用最大流算法

算法思想:網絡

  採用貪心的思想,每次找到一條從源點到達匯點的花費最小的路徑,增長流量,直到沒法找到一條從源點到達匯點的路徑,算法結束。 spa

  因爲最大流量有限,每執行一次循環流量都會增長,所以該算法確定會結束,且同時流量也一定會達到網絡的最大流量;同時因爲每次都是增長的最小的花費,即當前的最小花費是全部到達當前流量flow時的花費最小值,所以最後的總花費最小。
code

 

附上洛谷P3381模板題:blog

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<queue>
 5 using namespace std;  6 
 7 const int INF=0x7f7f7f7f;  8 const int MAXN=100000;  9 
10 struct Edge 11 { 12     int u,v,w,c,next;//u起點,v終點,w容量,c花費,next下一條邊
13 }E[MAXN]; 14 int node,head[MAXN]; 15 int pre[MAXN],cost[MAXN],vis[MAXN]; 16 int s,t; 17 int n,m,ans1,ans2; 18 
19 void insert(int u,int v,int w,int c) 20 { 21     E[++node]=(Edge){u,v,w,c,head[u]}; 22     head[u]=node; 23     E[++node]=(Edge){v,u,0,-c,head[v]}; 24     head[v]=node; 25 } 26 
27 bool spfa() 28 { 29     queue<int> Q; 30     memset(cost,0x7f,sizeof(cost)); 31  Q.push(s); 32     cost[s]=0;vis[s]=1; 33     while(!Q.empty()) 34  { 35         int q=Q.front();Q.pop(); 36         for(int i=head[q];i;i=E[i].next) 37             if(E[i].w&&cost[q]+E[i].c<cost[E[i].v]) 38  { 39                 cost[E[i].v]=cost[q]+E[i].c; 40                 pre[E[i].v]=i; 41                 if(!vis[E[i].v]) 42  { 43  Q.push(E[i].v); 44                     vis[E[i].v]=1; 45  } 46  } 47         vis[q]=0; 48  } 49     return cost[t]!=INF; 50 } 51 
52 void mcf() 53 { 54     int minn=INF; 55     for(int i=pre[t];i;i=pre[E[i].u]) 56         minn=min(minn,E[i].w); 57     for(int i=pre[t];i;i=pre[E[i].u]) 58  { 59         ans2+=minn*E[i].c; 60         E[i].w-=minn; 61         E[i^1].w+=minn; 62  } 63     ans1+=minn; 64 } 65 
66 int main() 67 { 68     scanf("%d%d%d%d",&n,&m,&s,&t); 69     for(int i=1;i<=m;i++) 70  { 71         int u,v,w,c; 72         scanf("%d%d%d%d",&u,&v,&w,&c); 73  insert(u,v,w,c); 74  } 75     while(spfa()) mcf(); 76     printf("%d %d",ans1,ans2);//ans1最大流 ans2最小費用
77     return 0; 78 }
相關文章
相關標籤/搜索