【洛谷 p3381】模板-最小费用最大流(图论)
题目:给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用。
解法:在Dinic的基础下做spfa算法。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<queue> 6 using namespace std; 7 8 const int N=5010,M=50010,INF=(int)1e9; 9 int n,m,st,ed,len=1; 10 int last[N],vis[N],id[N],pre[N],flow[N],d[N]; 11 struct node{int y,fl,co,next;}a[2*M]; 12 queue<int> q; 13 14 int mmin(int x,int y) {return x<y?x:y;} 15 void ins(int x,int y,int fl,int co) 16 { 17 a[++len].y=y,a[len].fl=fl,a[len].co=co; 18 a[len].next=last[x],last[x]=len; 19 a[++len].y=x,a[len].fl=0,a[len].co=-co; 20 a[len].next=last[y],last[y]=len; 21 } 22 bool spfa() 23 { 24 while (!q.empty()) q.pop(); 25 for (int i=1;i<=n;i++) d[i]=INF; 26 memset(vis,0,sizeof(vis)); 27 q.push(st); 28 d[st]=0,vis[st]=1,flow[st]=INF; 29 while (!q.empty()) 30 { 31 int x=q.front(); 32 q.pop(); vis[x]=0; 33 for (int i=last[x];i!=-1;i=a[i].next) 34 { 35 int y=a[i].y; 36 if (!a[i].fl) continue; 37 if (d[x]+a[i].co<d[y]) 38 { 39 d[y]=d[x]+a[i].co; 40 flow[y]=mmin(flow[x],a[i].fl); 41 id[y]=i, pre[y]=x; 42 if (!vis[y]) q.push(y), vis[y]=1; 43 } 44 } 45 } 46 return (d[ed]!=INF); 47 } 48 void Max_flow() 49 { 50 int sum=0,cost=0;; 51 while (spfa()) 52 { 53 sum+=flow[ed],cost+=d[ed]*flow[ed]; 54 for (int i=ed;i!=st;i=pre[i]) 55 { 56 a[id[i]].fl-=flow[ed]; 57 a[id[i]^1].fl+=flow[ed]; 58 } 59 } 60 printf("%d %d\n",sum,cost); 61 } 62 int main() 63 { 64 scanf("%d%d%d%d",&n,&m,&st,&ed); 65 int x,y,fl,co; 66 memset(last,-1,sizeof(last)); 67 for (int i=1;i<=m;i++) 68 { 69 scanf("%d%d%d%d",&x,&y,&fl,&co); 70 ins(x,y,fl,co); 71 } 72 Max_flow(); 73 return 0; 74 }