搭配飞行员

题意:

飞行大队有若干个来自各地的驾驶员,专门驾驶一种型号的飞机,这种飞机每架有两个驾驶员,
需一个正驾驶员和一个副驾驶员。由于种种原因,例如相互配合的问题,有些驾驶员不能在同
一架飞机上飞行,问如何搭配驾驶员才能使出航的飞机最多。
因为驾驶工作分工严格,两个正驾驶员或两个副驾驶员都不能同机飞行。
输入:
第一行,两个整数 n n n 与 m m m,表示共有 n n n 个飞行员,其中有 m m m 名飞行员是正驾驶员。
下面有若干行,每行有 2 2 2 个数字 a a a、b b b。表示正驾驶员 a a a 和副驾驶员 b b b 可以同机飞行。
注:正驾驶员的编号在前,即正驾驶员的编号小于副驾驶员的编号。

题解:

这是我除模板题以外的第一道网络流的题呐。

最大匹配问题,也可以用网络流做。
s向所有正驾驶连边(边权为1),正驾驶与可以匹配的副驾驶连边,副驾驶向t连边(边权为1),求出最大流即可。
易错:
注意不要把边加重了。
一开始,我在读入飞行员匹配关系的时候,读到哪一对,就连一条边,结果发现连重了。
因为一个副驾驶可能可以和多个正驾驶匹配,但是一个驾驶员只能向s/t连一条边。

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#define nn 110
#define mm 20010
#define inf 2000000001
using namespace std;
int get()
{
	int ans=0,f=1;char ch=getchar();
	while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)) {ans=ans*10+ch-'0';ch=getchar();}
	return ans*f;
}
int e=0,n,ss,tt,fir[nn],nxt[mm],to[mm],flow[mm],q[nn],dep[nn];
void add(int a,int b,int c)
{
	nxt[++e]=fir[a];fir[a]=e;to[e]=b;flow[e]=c;
	nxt[++e]=fir[b];fir[b]=e;to[e]=a;flow[e]=0;
}
bool bfs()
{
	int h=1,t=1,o;
	q[1]=ss;
	while(h<=t)
	  {
	  	o=q[h++];
	  	for(int i=fir[o];i;i=nxt[i])
	  	  if(flow[i]&&!dep[to[i]])
	  	    {
	  	    	dep[to[i]]=dep[o]+1;
	  	    	q[++t]=to[i];
			}
	  }
	if(dep[tt]) return 1;
	return 0;
}
int maxflow(int s,int f)
{
	if(!f||s==tt) return f;         //写成了return 0 
	int newflow,newans=0;
	for(int i=fir[s];i;i=nxt[i])
	  if(dep[to[i]]==dep[s]+1&&flow[i])
	    {
	    	newflow=maxflow(to[i],min(f,flow[i]));            //流量要和flow[i]取min 
	    	f-=newflow;
	    	flow[i]-=newflow;
	    	flow[i+1]+=newflow;
	    	newans+=newflow;
	    	if(!f) break;
		}
	if(f>0) dep[s]=-1;
	return newans;
}
int main()
{
    n=get();
	int m=get(),ans=0,s,e;
	ss=n+1,tt=n+2;
	while(scanf("%d%d",&s,&e)==2)
	  add(s,e,1);
	for(int i=1;i<=m;i++)
	  add(ss,i,1);
	for(int i=m+1;i<=n;i++)
	  add(i,tt,1);
	dep[ss]=1;
	while(bfs())
	  {
	  	ans+=maxflow(ss,inf);
	  	for(int i=1;i<=n+2;i++)         //算上ss、tt 
	  	  dep[i]=0;
	  	dep[ss]=1;
	  }
	printf("%d",ans);
	return 0;
}

  

posted @ 2017-08-30 09:45  o00v00o  阅读(165)  评论(0编辑  收藏  举报