在最大流有多组解时,给每条边在附上一个单位费用的量,问在知足最大流时的最小费用是多少?node
来搞清楚一些概念:ios
其实,就了解,解决最小费用最大流问题有两种思路:算法
通常使用第二种算法,有兴趣的同窗能够自学第一种;网络
给出一个容量网络,那他的最大流必定是一个定值(即便是有多个同样的最大值)。因此咱们从开始的可行流开始增广时,最终的增广量是必定的。因此为了知足最小费用咱们只须要每次找最小费用的增广路便可,直到流量为最大值。这个问题仅仅是在求增广路时先考虑费用最小的增广路,其余思想和EK思想同样。spa
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #define N 5010 #define M 50010 #define INF 0x3f3f3f3f using namespace std; int n,m,ss,tt; queue<int>q; int dis[N],minv[N]; bool vis[N]; struct Edge{int to;int value;int cost;int next;}e[M<<1]; struct Pre{int id;int node;}pre[M<<1]; int head[N],cnt=-1; void add(int from,int to,int value,int cost) { cnt++; e[cnt].to=to; e[cnt].value=value; e[cnt].cost=cost; e[cnt].next=head[from]; head[from]=cnt; } bool spfa(int s,int t) { q=queue<int>(); memset(dis,0x3f,sizeof(dis)); memset(vis,0,sizeof(vis)); memset(pre,-1,sizeof(pre)); memset(minv,0x3f,sizeof(minv)); dis[s]=0; vis[s]=1; q.push(s); while(!q.empty()) { int x=q.front(); q.pop(); vis[x]=0; for(int i=head[x];i>-1;i=e[i].next) { int now=e[i].to; if(dis[now]>dis[x]+e[i].cost&&e[i].value) { dis[now]=dis[x]+e[i].cost; minv[now]=min(minv[x],e[i].value); pre[now].id=i; pre[now].node=x; if(!vis[now]) { vis[now]=1; q.push(now); } } } } return dis[t]!=INF; } void MCMF(int s,int t,int &maxflow,int &mincost) { while(spfa(s,t)) { for(int i=t;i!=s;i=pre[i].node) { e[pre[i].id].value-=minv[t]; e[pre[i].id^1].value+=minv[t]; } maxflow+=minv[t]; mincost+=minv[t]*dis[t]; } } int main() { memset(head,-1,sizeof(head)); scanf("%d%d%d%d",&n,&m,&ss,&tt); for(int i=1;i<=m;i++) { int a,b,c,d; scanf("%d%d%d%d",&a,&b,&c,&d); add(a,b,c,d); add(b,a,0,-d); } int mf=0,mc=0; MCMF(ss,tt,mf,mc); printf("%d %d\n",mf,mc); return 0; }