zoukankan      html  css  js  c++  java
  • 搭配飞行员

    题意:

    飞行大队有若干个来自各地的驾驶员,专门驾驶一种型号的飞机,这种飞机每架有两个驾驶员,
    需一个正驾驶员和一个副驾驶员。由于种种原因,例如相互配合的问题,有些驾驶员不能在同
    一架飞机上飞行,问如何搭配驾驶员才能使出航的飞机最多。
    因为驾驶工作分工严格,两个正驾驶员或两个副驾驶员都不能同机飞行。
    输入:
    第一行,两个整数 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;
    }
    

      

  • 相关阅读:
    JDK1.0-缓冲流
    笔试错误1
    JVM 垃圾收集(转)
    Trie树和后缀树(转,简化)
    海量数据处理(转,简化)
    Struts2 内核之我见(转) -(主要是拦截器链和过滤链介绍和源码及其设计模式)
    phpize增加php模块
    Ubuntu下SVN安装和配置
    Linux下SVN配置hook经验总结
    Kruakal 算法——练习总结
  • 原文地址:https://www.cnblogs.com/charlotte-o/p/7451626.html
Copyright © 2011-2022 走看看