• [网络流24题]飞行员配对方案问题


    Description

    英国皇家空军从沦陷国征募了大量外籍飞行员。由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的2 名飞行员,其中1 名是英国飞行员,另1名是外籍飞行员。在众多的飞行员中,每一名外籍飞行员都可以与其他若干名英国飞行员很好地配合。如何选择配对飞行的飞行员才能使一次派出最多的飞机。对于给定的外籍飞行员与英国飞行员的配合情况,试设计一个算法找出最佳飞行员配对方案,使皇家空军一次能派出最多的飞机。

    对于给定的外籍飞行员与英国飞行员的配合情况,编程找出一个最佳飞行员配对方案,使皇家空军一次能派出最多的飞机。

    Code

    二分图匹配问题,可用最大流或匈牙利算法

    //最大流sap
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #define Inf 0x7fffffff
    #define N 110
    using namespace std;
    
    struct info{
    	int nex,to,f;
    }e[N*N];
    int n,m,Ans,dis[N],head[N],cnt[N],S,T,tot;
    
    void Link(int u,int v){
    	e[++tot].nex=head[u];
    	e[tot].f=1;e[tot].to=v;head[u]=tot;
    	e[++tot].nex=head[v];
    	e[tot].f=0;e[tot].to=u;head[v]=tot;
    }
    
    int sap(int u,int delta){
    	int sum=0,mins=n;
    	if(u==T) return delta;
    	
    	for(int i=head[u];i;i=e[i].nex){
    		int v=e[i].to;
    		if(e[i].f>0&&dis[u]==dis[v]+1){
    			int save=sap(v,min(delta-sum,e[i].f));
    			sum+=save;
    			e[i].f-=save;
    			e[i^1].f+=save;
    			if(dis[S]>=n||sum==delta) return sum;
    		}
    		if(e[i].f>0) mins=min(mins,dis[v]);
    	}
    	if(sum==0){
    		if(!(--cnt[dis[u]])) dis[S]=n;
    		else ++cnt[dis[u]=mins+1];
    	}
    	return sum;
    }
    
    int main(){
    	scanf("%d%d",&m,&n);
    	S=0,T=n+1;tot=-1;
    	int u,v,tmp;
    	while(~scanf("%d%d",&u,&v)){
    		if(u+v==-2) break;
    		Link(u,v);
    	}
    	for (int i=1;i<=m;++i) Link(S,i);
        for (int i=m+1;i<=n;++i) Link(i,T);
        n+=2;cnt[0]=n;
    	while(dis[S]<n) Ans+=sap(S,Inf);
    	printf("%d
    ",Ans);
    	for(int i=0;i<=tot;i+=2)//输出方案
    		if(e[i].fr!=S&&e[i].to!=S&&e[i].fr!=T&&e[i].to!=T&&e[i^1].f!=0)
    			printf("%d %d
    ",e[i].fr,e[i].to);
    	return 0;
    }
    

    匈牙利,

    #include <cstdio>
    #include <cstring>
    #define N 110
    using namespace std;
    
    int n,m,ans=0,node[N];
    bool line[N][N],used[N];
    
    bool find(int k)
    {
        for(int i=1;i<=m;++i)
        {
            if(line[k][i]&&!used[i])
            {
                used[i]=1;
                if(!node[i]||find(node[i]))
                {
                    node[i]=k;
                    return 1;
                }
            }
        }
        return 0;
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        int a,b;
        while(1)
        {
            scanf("%d%d",&a,&b);
            if(a==-1&&b==-1) break;
            line[a][b]=1;
        }
        for(int i=1;i<=n;++i)
        {
            memset(used,0,sizeof(used));
            if(find(i)) ++ans;
        }
        if(!ans)
        {
            printf("No Solution!
    ");
            return 0;
        }
        printf("%d
    ", ans);
        for(int i=1;i<=m;++i)
            if(node[i])
        	{
            	printf("%d %d
    ", node[i],i);
        	}
        return 0;
    }
    
  • 相关阅读:
    RequireJS的简单应用
    关于浏览器兼容处理—— 识别IE浏览器
    Div+CSS命名规范
    用CSS开启硬件加速来提高网站性能(转)
    5步解决移动设备上的300ms点击延迟
    全面理解BFC
    纯CSS画的基本图形(矩形、圆形、三角形、多边形、爱心、八卦等)
    Less和Sass编译
    Linux初级知识_03 -- 系统基础命令
    Linux初级知识_02 -- 基础命令
  • 原文地址:https://www.cnblogs.com/void-f/p/8287052.html
Copyright © 2020-2023  润新知