模板—费用流(最小费用最大流)

模板—费用流(最小费用最大流)

Code:

#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define inf 1000000000
#define N 100010
#define M 1000010
int idx=1,n,m,s,t,ans,dist[N]; bool vis[N];
int head[N],to[M<<2],val[M<<2],cost[M<<2],nxt[M<<2];
void add(int a,int b,int c,int d)
	{nxt[++idx]=head[a],to[idx]=b,val[idx]=c,cost[idx]=d,head[a]=idx;}
bool spfa(int s,int t)
{
	memset(vis,0,sizeof vis);
	for(int i=1;i<=n;i++) dist[i]=inf; dist[t]=0,vis[t]=1;
	deque <int> q; q.push_back(t);
	while(!q.empty())
	{
		int p=q.front(); q.pop_front();
		for(int i=head[p];i;i=nxt[i])
			if(val[i^1]&&dist[to[i]]>dist[p]-cost[i])
			{
				dist[to[i]]=dist[p]-cost[i];
				if(!vis[to[i]])
				{
					vis[to[i]]=true;
					if((!q.empty())&&dist[to[i]]<dist[q.front()]) q.push_front(to[i]);
					else q.push_back(to[i]);
				}
			}
		vis[p]=false;
	} return dist[s]<inf;
}
int dfs(int p,int flow)
{
	int temp=flow,now; vis[p]=true;
	if(p==t) return flow;
	for(int i=head[p];i;i=nxt[i])
		if((!vis[to[i]])&&val[i]&&dist[p]-cost[i]==dist[to[i]])
		{
			now=dfs(to[i],min(temp,val[i]));
			if(now) ans+=now*cost[i],val[i]-=now,val[i^1]+=now,temp-=now;
			if(!temp) break;
		} return flow-temp;
}
int costflow()
{
	int flow=0;
	while(spfa(s,t))
	{
		vis[t]=true;
		while(vis[t]) memset(vis,0,sizeof vis),flow+=dfs(s,inf);
	} return flow;
}
int main()
{
	scanf("%d%d%d%d",&n,&m,&s,&t);
	for(int i=1,a,b,c,d;i<=m;i++) scanf("%d%d%d%d",&a,&b,&c,&d),add(a,b,c,d),add(b,a,0,-d);
	printf("%d ",costflow()),printf("%d\n",ans);
}

猜你喜欢

转载自www.cnblogs.com/yangsongyi/p/10658881.html