最小费用最大流
在网络流的基础上,在每条边上增加一个单位流量费用的限制,这样的问题就是最小费用最大流。
解决该问题的算法时基于贪心的思想,每次找到从源点到会点费用最小的增广路径,直到不存在增广路为止。
P3381 【模板】最小费用最大流
参考代码
#include<bits/stdc++.h>
using namespace std;
const int N=5e3+10;
const int M=2*5e4+10;
int head[N],cnt=1;
struct{
int v,next,w,c;
}e[M];
int n,m,s,t;
inline void add(int u,int v,int w,int c){
e[++cnt].c=c;
e[cnt].next=head[u];
head[u]=cnt;
e[cnt].v=v;
e[cnt].w=w;
}
int pren[N],prem[N],vis[N],dist[N],flow[N];
queue<int>q;
bool spfa(){
memset(vis,0,sizeof(vis));
memset(dist,0x3f,sizeof(dist));
q.push(s);vis[s]=1;flow[s]=INT_MAX;
dist[s]=0;
int u,v,w,c;
while(q.size()){
u=q.front();q.pop();vis[u]=0;
for(int i=head[u];i;i=e[i].next){
v=e[i].v;w=e[i].w;c=e[i].c;
if(w&&dist[v]>dist[u]+c){
dist[v]=dist[u]+c;
pren[v]=u;
prem[v]=i;
flow[v]=min(flow[u],w);
if(!vis[v]){
vis[v]=1;
q.push(v);
}
}
}
}
return dist[t]!=0x3f3f3f3f;
}
int ans=0,cost;
void mcmf(){
while(spfa()){
// printf("%d %d\n",flow[t],dist[t]);
int now=t,f=flow[t];
ans+=f;cost+=f*dist[t];
while(now!=s){
e[prem[now]].w-=f;
e[prem[now]^1].w+=f;
now=pren[now];
}
}
return ;
}
int main(){
scanf("%d%d%d%d",&n,&m,&s,&t);
int u,v,w,c;
for(int i=1;i<=m;++i){
scanf("%d%d%d%d",&u,&v,&w,&c);
add(u,v,w,c);add(v,u,0,-c);
}
mcmf();
printf("%d %d",ans,cost);
return 0;
}