网络流之最大流 学习笔记

网络流之费用流(最小费用最大流)

Dinic

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 100010
#define M 500010
#define maxn 2147483647
int last[N],len=1;
int dis[N],q[N],p[N],cur[N];
struct
{
	int c,to,next;
}a[M*2];
int n,m;
void add(int x,int y,int c)
{
	a[++len].to=y;
	a[len].next=last[x];
	a[len].c=c;
	last[x]=len;
}
int bfs()
{
	memset(dis,0,sizeof(dis));
	dis[1]=1,q[1]=1;
	int l=0,r=1;
	while(l<r)
	{
		int k=q[++l];
		for(int i=last[k];i;i=a[i].next) 
		{
			if(!dis[a[i].to]&&a[i].c) 
			{
				dis[a[i].to]=dis[k]+1;
				q[++r]=a[i].to;
			}
		}
	}
	return dis[n];
}
int dfs(int k,int flow)
{
	if(k==n) return flow;
	int have=0;
	for(int i=cur[k];i;i=a[i].next)
	{
		if(dis[k]+1==dis[a[i].to]&&a[i].c)
		{
			int now=dfs(a[i].to,min(flow-have,a[i].c));
			have+=now,a[i].c-=now,a[i^1].c+=now;
			if(have==flow) return flow;
		}
		cur[k]=i;
	}
	cur[k]=last[k];
	return have;
}
int main()
{
	int i,x,y,c,w;
	scanf("%d%d",&n,&m);
	for(i=1;i<=m;i++)
	{
		scanf("%d%d%d",&x,&y,&c);
		add(x,y,c);
		add(y,x,0);
	}
	int sum=0;
	while(bfs())
	{
		while(1)
		{
			int t=dfs(1,maxn);
			if(t) sum+=t; else break;
		}
	}
	printf("%d",sum);
	return 0;
} 

SAP+GAP优化

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 100010
#define M 500010
int cur[N],gap[N],dis[N];
int to[M*2],last[N],next[M*2],ln[M*2],len=1;
int n,m,s,t;
void add(int x,int y,int l)
{
	to[++len]=y;
	next[len]=last[x];
	ln[len]=l;
	last[x]=len;
}
int dfs(int k,int flow)
{
	if(k==t) return flow;
	int have=0;
	for(int i=cur[k];i;i=next[i])
	{
		if(dis[to[i]]+1==dis[k]&&ln[i])	
		{
			int now=dfs(to[i],min(flow-have,ln[i]));
			have+=now;
			ln[i]-=now,ln[i^1]+=now;
			if(flow==have) return have;
		}
		cur[k]=i;
	}
	cur[k]=last[k];
	gap[dis[k]]--;
	if(!gap[dis[k]]) dis[1]=n;
	gap[++dis[k]]++;
	return have;
	
}
int main()
{
	int i,x,y,l;
	scanf("%d%d%d%d",&n,&m,&s,&t);
	for(i=1;i<=m;i++) 
	{
		scanf("%d%d%d",&x,&y,&l);
		add(x,y,l),add(y,x,0);
	}
	gap[0]=n;
	long long sum=0;
	while(dis[s]<n) sum+=dfs(s,2147483647);
	printf("%lld",sum);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39565901/article/details/103325430