123789456ye

已AFO

网络流模板

内容均来自以下两个blog
EK与dinic
ISAP与HLPP

最大流

最普通的版本(dinic)

#include<bits/stdc++.h>
using namespace std;
#define maxm 200005
#define maxn 10010
#define inf 0x3f3f3f3f
struct Edge
{
	int fr,to,val;
}eg[maxm];
int edgenum=1,maxflow,n,m,head[maxn];
inline void add(int fr,int to,int val)
{
	eg[++edgenum].fr=head[fr];
	eg[edgenum].to=to;
	eg[edgenum].val=val;
	head[fr]=edgenum;
}
int deep[maxn],vis[maxn],s,t;
bool bfs()
{
	memset(deep,0x3f,sizeof(deep));
	memset(vis,0,sizeof(vis));
	deep[s]=0;
	queue<int> q;
	q.push(s);
	while(!q.empty())
	{
		int tmp=q.front();
		q.pop();
		vis[tmp]=0;
		for(int i=head[tmp];i;i=eg[i].fr)
		{
			int to=eg[i].to;
			if(deep[to]>deep[tmp]+1&&eg[i].val)
			{
				deep[to]=deep[tmp]+1;
				if(!vis[to])
					vis[to]=1,q.push(to);
			}
		}
	}
	if(deep[t]!=inf) return 1;
	return 0;
}
inline int dfs(int now,int flow)
{
	if(now==t) return flow;
	int tmpflow=0;
	for(int i=head[now];i;i=eg[i].fr)
	{
		int to=eg[i].to;
		if(deep[to]==deep[now]+1&&eg[i].val)
		{
			if(tmpflow=dfs(to,min(flow,eg[i].val)))
			{
				eg[i].val-=tmpflow;
				eg[i^1].val+=tmpflow;
				return tmpflow;
			}
		}
	}
	return 0;
}
void dinic()
{
	int lowflow;
	while(bfs())
		while(lowflow=dfs(s,inf)) maxflow+=lowflow;
}
int main()
{
	scanf("%d%d%d%d",&n,&m,&s,&t);
	int u,v,w;
	for(int i=1;i<=m;++i)
	{
		scanf("%d%d%d",&u,&v,&w);
		add(u,v,w);
		add(v,u,0);
	}
	dinic();
	printf("%d\n",maxflow);
	return 0;
}

加上多路增广和当前弧

#include<bits/stdc++.h>
using namespace std;
#define maxm 200005
#define maxn 10010
#define inf 0x3f3f3f3f
struct Edge
{
	int fr,to,val;
}eg[maxm];
int edgenum=1,maxflow,n,m,head[maxn],cur[maxn];
inline void add(int fr,int to,int val)
{
	eg[++edgenum].fr=head[fr];
	eg[edgenum].to=to;
	eg[edgenum].val=val;
	head[fr]=edgenum;
}
int deep[maxn],vis[maxn],s,t;
bool bfs()
{
	for(register int i=0;i<=n;++i) deep[i]=inf,vis[i]=0,cur[i]=head[i];
	deep[s]=0;
	queue<int> q;
	q.push(s);
	while(!q.empty())
	{
		int tmp=q.front();
		q.pop();
		vis[tmp]=0;
		for(int i=head[tmp];i;i=eg[i].fr)
		{
			int to=eg[i].to;
			if(deep[to]>deep[tmp]+1&&eg[i].val)
			{
				deep[to]=deep[tmp]+1;
				if(!vis[to])
					vis[to]=1,q.push(to);
			}
		}
	}
	if(deep[t]!=inf) return 1;
	return 0;
}
inline int dfs(int now,int flow)
{
	if(now==t)
	{
		maxflow+=flow;
		return flow;
	}
	int tmpflow=0,used=0;
	for(int i=cur[now];i;i=eg[i].fr)
	{
		int to=eg[i].to;
		cur[now]=i;
		if(deep[to]==deep[now]+1&&eg[i].val)
		{
			if(tmpflow=dfs(to,min(flow-used,eg[i].val)))
			{
				used+=tmpflow;
				eg[i].val-=tmpflow;
				eg[i^1].val+=tmpflow;
				if(used==flow) break;
			}
		}
	}
	return used;
}
inline void dinic()
{
	while(bfs()) dfs(s,inf);
}
int main()
{
	scanf("%d%d%d%d",&n,&m,&s,&t);
	int u,v,w;
	for(int i=1;i<=m;++i)
	{
		scanf("%d%d%d",&u,&v,&w);
		add(u,v,w);
		add(v,u,0);
	}
	dinic();
	printf("%d\n",maxflow);
	return 0;
}

ISAP(当前弧)话说为什么不能跑费用流啊

#include<bits/stdc++.h>
using namespace std;
#define maxm 200005
#define maxn 10010
#define inf 0x3f3f3f3f
struct Edge
{
	int fr,to,val;
}eg[maxm];
int edgenum=1,maxflow,n,m,head[maxn],cur[maxn],gap[maxn];
inline void add(int fr,int to,int val)
{
	eg[++edgenum]=(Edge){head[fr],to,val};
	head[fr]=edgenum;
}
int deep[maxn],s,t;
void bfs()
{
	for(register int i=0;i<=n;++i) deep[i]=-1,gap[i]=0;
	deep[t]=0;
	gap[0]=1;
	queue<int> q;
	q.push(t);
	while(!q.empty())
	{
		int tmp=q.front();
		q.pop();
		for(int i=head[tmp];i;i=eg[i].fr)
		{
			int to=eg[i].to;
			if(deep[to]==-1)
			{
				q.push(to);
				deep[to]=deep[tmp]+1;
				++gap[deep[to]];
			}
		}
	}
}
inline int dfs(int now,int flow)
{
	if(now==t)
	{
		maxflow+=flow;
		return flow;
	}
	int tmpflow=0,used=0;
	for(int i=cur[now];i;i=eg[i].fr)
	{
		int to=eg[i].to;
		cur[now]=i;
		if(deep[to]+1==deep[now]&&eg[i].val)
		{
			if(tmpflow=dfs(to,min(flow-used,eg[i].val)))
			{
				used+=tmpflow;
				eg[i].val-=tmpflow;
				eg[i xor 1].val+=tmpflow;
			}
			if(used==flow) return used;
		}
	}
	if(!--gap[deep[now]]) deep[s]=n+1;
	++gap[++deep[now]];
	return used;
}
inline void ISAP()
{
	bfs();
	while(deep[s]<n)
	{
		memcpy(cur,head,sizeof(head));
		dfs(s,inf);
	}
}
int main()
{
	scanf("%d%d%d%d",&n,&m,&s,&t);
	int u,v,w;
	for(int i=1;i<=m;++i)
	{
		scanf("%d%d%d",&u,&v,&w);
		add(u,v,w);
		add(v,u,0);
	}
	ISAP();
	printf("%d\n",maxflow);
	return 0;
}

HLPP先咕了


最小费用最大流

dinic+spfa

#include<bits/stdc++.h>
using namespace std;
#define maxm 100005
#define maxn 5010
#define inf 0x3f3f3f3f
struct Edge
{
	int fr,to,val,wei;
}eg[maxm];
int edgenum=1,maxflow,mincost,n,m,head[maxn],cur[maxn];
inline void add(int fr,int to,int val,int wei)
{
	eg[++edgenum]=(Edge){head[fr],to,val,wei};
	head[fr]=edgenum;
}
int dis[maxn],vis[maxn],s,t;
bool bfs()
{
	for(register int i=0;i<=n;++i) dis[i]=inf,vis[i]=0,cur[i]=head[i];
	dis[s]=0;
	queue<int> q;
	q.push(s);
	while(!q.empty())
	{
		int tmp=q.front();
		q.pop();
		vis[tmp]=0;
		for(int i=head[tmp];i;i=eg[i].fr)
		{
			int to=eg[i].to;
			if(dis[to]>dis[tmp]+eg[i].wei&&eg[i].val)
			{
				dis[to]=dis[tmp]+eg[i].wei;
				if(!vis[to])
					vis[to]=1,q.push(to);
			}
		}
	}
	if(dis[t]!=inf) return 1;
	return 0;
}
inline int dfs(int now,int flow)
{
	if(now==t)
	{
		vis[t]=1;
		maxflow+=flow;
		return flow;
	}
	vis[now]=1;
	int tmpflow=0,used=0;
	for(int i=cur[now];i;i=eg[i].fr)
	{
		int to=eg[i].to;
		cur[now]=i;
		if((!vis[to]||to==t)&&dis[to]==dis[now]+eg[i].wei&&eg[i].val)
		{
			if(tmpflow=dfs(to,min(flow-used,eg[i].val)))
			{
				used+=tmpflow;
				mincost+=eg[i].wei*tmpflow;
				eg[i].val-=tmpflow;
				eg[i^1].val+=tmpflow;
				if(used==flow) break;
			}
		}
	}
	return used;
}
inline void dinic()
{
	while(bfs()) dfs(s,inf);
}
int main()
{
	scanf("%d%d%d%d",&n,&m,&s,&t);
	int u,v,w,h;
	for(int i=1;i<=m;++i)
	{
		scanf("%d%d%d%d",&u,&v,&w,&h);
		add(u,v,w,h);
		add(v,u,0,-h);
	}
	dinic();
	printf("%d %d\n",maxflow,mincost);
	return 0;
}
posted @ 2019-08-05 20:24  123789456ye  阅读(166)  评论(0编辑  收藏  举报