最小费用最大流模板

没什么好说的,直接上代码吧~
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#define InsE(x,y,c,b,P) cost[P]=b,cap[P]=c,v[P]=y,next[P]=head[x],head[x]=P++
#define add(x) Q.push(x),vis[x]=1
#define del(x) x=Q.front(),Q.pop(),vis[x]=0
#define clean(x,y) memset(x,y,sizeof(x))
#define loop(i,u) for(i=p[t][0],u=p[t][1];i!=-1;i=p[u][0],u=p[u][1])
#define MaxN 110
#define MaxM 10010
using namespace std;
const int INF=~0U>>2;
int v[MaxM],cap[MaxM],cost[MaxM],next[MaxM]; //struct of edge
int head[MaxN],d[MaxN],p[MaxN][2];           //rec of shortest path
bool vis[MaxN];
int n,m,tot,MaxFlow,MinCost;
inline void AddEdge(const int &x,const int &y,const int &c,const int &w)
{
	InsE(x,y,c,w,tot);
	InsE(y,x,0,-w,tot);
}
inline void init()
{
	int x,y,c,w;
	cin>>n>>m;
	clean(head,-1);
	while(m--)
	{
		scanf("%d%d%d%d",&x,&y,&c,&w);
		AddEdge(x,y,c,w);
	}
}
inline bool spfa(const int &s,const int &t)
{
	clean(p,-1);
	clean(vis,0);
	for(int i=2;i<=n;i++) d[i]=INF;
	d[s]=0;
	queue<int> Q;
	add(s);
	int x,y,i,u;
	while(!Q.empty())
	{
		del(x);
		for(i=head[x],y=v[i];i!=-1;i=next[i],y=v[i])
			if(cap[i]>0&&d[y]>d[x]+cost[i])
			{
				d[y]=d[x]+cost[i];
				p[y][0]=i,p[y][1]=x;
				if(!vis[y]) add(y);
			}
	}
	return d[t]!=INF;
}
inline void work()
{
	int s=1,t=n,ans=0,i,u,flow;
	while(spfa(s,t))
	{
		flow=INF;
		loop(i,u)
			if(flow>cap[i])
				flow=cap[i];
		MaxFlow+=flow;
		loop(i,u)
		{
			cap[i]-=flow;
			cap[i^1]+=flow;
		}
		ans+=flow*d[t];
	}
	cout<<"MaxFlow:"<<MaxFlow<<endl;
	cout<<"MinCost:"<<ans<<endl;
}
int main()
{
	init();
	work();
	return 0;
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值