【网络流24题】 飞行员配对方案问题

题目

luogu2756

代码

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdio>
#define N 40005
#define inf 2000000000
using namespace std;

int m,n,s,t,ans,link[N]; 

struct node
{
	int to,nt,cap;
}edge[N];

int num=1,p[N];//因为建正反边,查找的时候会用到^,num一定要从1开始
void add(int x,int y,int w)
{
	edge[++num].to=y;edge[num].cap=w;
	edge[num].nt=p[x];p[x]=num;
	edge[++num].to=x;edge[num].cap=0;
	edge[num].nt=p[y];p[y]=num;
}

int d[N],q[N];
bool bfs()
{
	memset(d,-1,sizeof(d));
	int head=0,tail=0;
	d[s]=0;q[++tail]=s;
	while(head<tail)
	{
		int k=q[++head];
		for(int e=p[k];e;e=edge[e].nt)
		{
			int kk=edge[e].to;
			if(d[kk]==-1&&edge[e].cap)
			{
				d[kk]=d[k]+1;
				q[++tail]=kk;
			}
		}
	}
	return d[t]>=0;
}

int dfs(int x,int f)
{
	if(x==t) return f;
	for(int e=p[x];e;e=edge[e].nt)
	{
		int kk=edge[e].to;
		if(d[kk]==d[x]+1&&edge[e].cap)
		{
			int ff=dfs(kk,min(edge[e].cap,f));
			if(ff>0)
			{
				link[x]=kk; 
				edge[e].cap-=ff;
				edge[e^1].cap+=ff;
				return ff;
			}
		} 
	}
	return 0;
}

int main()
{
	scanf("%d%d",&m,&n);
	s=0;t=n+1;
	for(int i=1;i<=m;i++) add(s,i,1);
	for(int i=m+1;i<=n;i++) add(i,t,1);
	int i,j;scanf("%d%d",&i,&j);
	while(!(i==-1&&j==-1))
	{
		add(i,j,1);
		scanf("%d%d",&i,&j);
	}
	while(bfs())
	{
		int f;
		while(f=dfs(s,inf)) ans+=f;
	}
	if(ans)
	{
		printf("%d\n",ans);
		for(int i=1;i<=m;i++) 
			if(link[i]) printf("%d %d\n",i,link[i]);
	}
	else printf("No Solution!");
	return 0;
}
posted @ 2017-08-17 10:23  XYZinc  阅读(171)  评论(0编辑  收藏  举报