网络流模板:最大流ISAP算法和Dinic算法

ISAP:

 

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define N 505
#define inf 999999999
using namespace std;

int n,m,s,t,dis[N],pre[N],gap[N],flow[N][N];
struct edge
{
	int v,w;
	edge *next,*rev;
	edge(){next=0;}
	edge(int vv,int ww,edge *e){v=vv;w=ww;next=e;}
}*adj[N],*path[N],*e;
void insert(int u,int v,int w)
{
	edge *p=new edge(v,w,adj[u]);
	adj[u]=p;
	edge *q=new edge(u,0,adj[v]);
	adj[v]=q;
	p->rev=q;
	q->rev=p;
}
void bfs()
{
	memset(dis,0x7f,sizeof(dis));
	memset(gap,0,sizeof(gap));
	queue<int> q;
	dis[t]=0;
	gap[0]=1;
	q.push(t);
	while(q.size())
	{
		int x=q.front();
		q.pop();
		for(e=adj[x];e;e=e->next)
		{
			if(e->rev->w==0||dis[e->v]<t)
				continue;
			dis[e->v]=dis[x]+1;
			++gap[dis[e->v]];
			q.push(e->v);
		}
	}
}
int ISAP()
{
	memset(dis,0,sizeof(dis));
	memset(gap,0,sizeof(gap));
	//bfs();
	int ans=0,u=s,d;
	while(dis[s]<=t)
	{
		if(u==t)
		{
			int minflow=-1u>>1;
			for(e=path[u];u!=s;e=path[u=pre[u]])
				minflow=min(minflow,e->w);
			for(e=path[u=t];u!=s;e=path[u=pre[u]])
			{
				e->w-=minflow;
				e->rev->w+=minflow;
				flow[pre[u]][u]+=minflow;
				flow[u][pre[u]]-=minflow;
			}
			ans+=minflow;
		}		
		for(e=adj[u];e;e=e->next)
			if(e->w>0&&dis[u]==dis[e->v]+1)
				break;
		if(e)
		{
			pre[e->v]=u;
			path[e->v]=e;
			u=e->v;
		}
		else
		{
			if(--gap[dis[u]]==0)
				break;
			for(d=t,e=adj[u];e;e=e->next)
				if(e->w>0)
					d=min(d,dis[e->v]);
			dis[u]=d+1;
			++gap[dis[u]];
			if(u!=s)
				u=pre[u];
		}
	}
	return ans;
}
int main()
{
	int u,v,w;
	while(~scanf("%d%d",&m,&n))
	{
		memset(adj,0,sizeof(adj));
		while(m--)
		{
			scanf("%d%d%d",&u,&v,&w);
			insert(u,v,w);
			//insert(v,u,w);//无向边
		}
		s=1;
		t=n;
		printf("%d\n",ISAP());
	}
}
/*
6 5
3 4 5
4 5 5
1 2 10
2 3 10
1 3 20
2 5 20

*/


 

Dinic:

 

#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 5005
#define M 10005
#define inf 999999999
using namespace std;

int n,m,s,t,num,adj[N],dis[N],q[N];
struct edge
{
	int v,w,pre;
}e[M];
void insert(int u,int v,int w)
{
	e[num]=(edge){v,w,adj[u]};
	adj[u]=num++;
	e[num]=(edge){u,0,adj[v]};
	adj[v]=num++;
}
int bfs()
{
	int i,x,v,tail=0,head=0;
	memset(dis,0,sizeof(dis));
	dis[s]=1;
	q[tail++]=s;
	while(head<tail)
	{
		x=q[head++];		
		for(i=adj[x];i!=-1;i=e[i].pre)
			if(e[i].w&&dis[v=e[i].v]==0)
			{
				dis[v]=dis[x]+1;
				if(v==t)
					return 1;
				q[tail++]=v;
			}
	}
	return 0;
}
int dfs(int s,int limit)
{
	if(s==t)
		return limit;
	int i,v,tmp,cost=0;
	for(i=adj[s];i!=-1;i=e[i].pre)
		if(e[i].w&&dis[s]==dis[v=e[i].v]-1)
		{
			tmp=dfs(v,min(limit-cost,e[i].w));
			if(tmp>0)
			{
				e[i].w-=tmp;
				e[i^1].w+=tmp;
				cost+=tmp;
				if(limit==cost)
					break;
			}
			else dis[v]=-1;
		}
	return cost;
}
int Dinic()
{
	int ans=0;
	while(bfs())
		ans+=dfs(s,INT_MAX);
	return ans;
}
int main ()
{
	while(~scanf("%d%d",&m,&n))
	{
		int u,v,w;
		memset(adj,-1,sizeof(adj));
		num=0;
		s=1;
		t=n;
		while(m--)
		{
			scanf("%d%d%d",&u,&v,&w);
			insert(u,v,w);
		}
		printf("%d\n",Dinic());
	}
}


 

你可能感兴趣的:(算法,网络,struct,insert,Path)