洛谷 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!’。
输入输出样例
5 10 1 7 1 8 2 6 2 9 2 10 3 7 3 8 4 7 4 8 5 10 -1 -1
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\n",ans); for(int i=m+1;i<=n;i++) if(pair[i]) printf("%d %d\n",pair[i],i); return 0; }