zoukankan      html  css  js  c++  java
  • 洛谷 P2756 飞行员配对方案问题

    题目背景

    第二次世界大战时期..

    题目描述

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

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

    输入输出格式

    输入格式:

    第 1 行有 2 个正整数 m 和 n。n 是皇家空军的飞行员总数(n<100);m 是外籍飞行员数(m<=n)。外籍飞行员编号为 1~m;英国飞行员编号为 m+1~n。

    接下来每行有 2 个正整数 i 和 j,表示外籍飞行员 i 可以和英国飞行员 j 配合。最后以 2个-1 结束。

    输出格式:

    第 1 行是最佳飞行员配对方案一次能派出的最多的飞机数 M。接下来 M 行是最佳飞行员配对方案。每行有 2个正整数 i 和 j,表示在最佳飞行员配对方案中,飞行员 i 和飞行员 j 配对。如果所求的最佳飞行员配对方案不存在,则输出‘No Solution!’。

    输入输出样例

    输入样例#1:
    5 10
    1 7
    1 8
    2 6
    2 9
    2 10
    3 7
    3 8
    4 7
    4 8
    5 10
    -1 -1
    输出样例#1://本题SPJ好评,只要总匹配数对了,输出的匹配不一定按照样例输出,颠倒顺序或替换一些匹配也是能得分的
    4
    1 7
    2 9
    3 8
    5 10 

    解题思路

      裸的二分图最大匹配,这题的数据范围可以直接套上匈牙利算法的板子。之前做的题因为数据范围太大没敢用邻接矩阵存图,这次总算有机会了……

      还可以用最大流解,详见二分图最大匹配

      个人感觉匈牙利在OI中应用不太广,目前我只知道匈牙利专门对付二分图最大匹配,好像没别的作用了……网络流用途就广泛得多,没做过的童鞋可以做一下传说中的网络流24题,里面有许多神奇的建图技巧,一道难题经过一些神奇的转换之后就成了一道网络流的题目,就能直接套上板子了。这题就是其中的T1。

    #include<stdio.h>
    #include<string.h>
    int n,m,ans=0;
    int g[105][105]={0};
    int pair[105];
    bool vis[105]={0};
    
    bool dfs(int u)
    {
        for(int i=m+1;i<=n;i++)
        {
            if(!g[u][i])continue;
            if(!vis[i])
            {
                vis[i]=1;
                if(!pair[i]||dfs(pair[i]))
                {
                    pair[i]=u;
                    return 1;
                }
            }
        }
        return 0;
    }
    
    int main()
    {
        scanf("%d%d",&m,&n);
        for(int u,v;;)
        {
            scanf("%d%d",&u,&v);
            if(u==-1&&v==-1) break;
            g[u][v]=g[v][u]=1;
        }
        for(int i=1;i<=m;i++)
        {
            memset(vis,0,sizeof(vis));
            if(dfs(i)) ans++;
        }
        printf("%d
    ",ans);
        for(int i=m+1;i<=n;i++)
            if(pair[i])    printf("%d %d
    ",pair[i],i);
        return 0;
    }
  • 相关阅读:
    重新进入学习模式
    第八章 函数
    第七章 用户输入和while语句
    第6章 字典
    第五章 if语句
    对前四章方法、函数、语句的总结
    完成四个章节的学习,我觉得有必要花一天的时间对各章节内的函数、方法、语句进行总结。明后天不再对新章节进行学习。
    第四章 操作列表
    第三章 列表简介
    C语言数据结构-折半查找
  • 原文地址:https://www.cnblogs.com/wawcac-blog/p/6910436.html
Copyright © 2011-2022 走看看