最大流: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 }