网络流_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 }
相关文章
相关标签/搜索