注:本题在Codevs上有原题,但因为缺少Special Judge而无法通过。请想要数据的Oier通过邮箱联系我(邮箱请见左上角)。
飞行员配对方案问题
Description
第二次世界大战时期,英国皇家空军从沦陷国征募了大量外籍飞行员。
由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的
2
名飞行员。
其中,
在众多的飞行员中,每一名外籍飞行员都可以与其他若干名英国飞行员很好地配合。
现在的问题是,如何选择配对飞行的飞行员才能使一次派出最多的飞机。
对于给定的外籍飞行员与英国飞行员的配合情况,试设计一个算法找出最佳飞行员配对方案,使皇家空军一次能派出最多的飞机。
Input
由文件
文件第
1
行有
n
是皇家空军的飞行员总数
外籍飞行员编号为
接下来每行有
文件最后以
2
个
Output
程序运行结束时,将最佳飞行员配对方案输出到文件
output.txt
中。
第
1
行是最佳飞行员配对方案一次能派出的最多的飞机数
接下来
M
行是最佳飞行员配对方案。
每行有
如果所求的最佳飞行员配对方案不存在,则输出“
NoSolution!
”
Sample Input
5 10
1 7
1 8
2 6
2 9
2 10
3 7
3 8
4 7
4 8
5 10
-1 -1
Sample Output
4
1 7
2 9
3 8
5 10
Solution
本题就是一个典型的二分图最大匹配问题,可以当作最大流问题来解决。
我给出的求最大流的代码是
Dinic
算法(输出方案的部分我图省事,打得比较丑)。
- #include <iostream>
- #include <cstring>
- #include <cstdio>
- #include <queue>
- #include <algorithm>
- #define Min(a,b) ((a)<(b)?(a):(b))
- using namespace std;
- struct ans{
- int a,b;
- }ANS[1000];
- bool cmp(ans a,ans b){
- return a.a<b.a||(a.a==b.a&&a.b<b.b);
- }
- const int INF=0x3f3f3f3f;
- const int MAXN=10000;
- queue<int>q;
- int data[MAXN*2],weight[MAXN*2];
- int nxt[MAXN*2],head[MAXN],dis[MAXN],from[MAXN*2];
- int n,m,cnt,s,t,ANSS;
- void add(int x,int y,int z){
- from[cnt]=x;nxt[cnt]=head[x];data[cnt]=y;weight[cnt]=z;head[x]=cnt++;
- from[cnt]=y;nxt[cnt]=head[y];data[cnt]=x;weight[cnt]=0;head[y]=cnt++;
- }
- bool BFS(){
- memset(dis,-1,sizeof dis);
- dis[s]=0;
- q.push(s);
- while(!q.empty()){
- int now=q.front();
- q.pop();
- for(int i=head[now];i!=-1;i=nxt[i])if(dis[data[i]]<0&&weight[i]){
- dis[data[i]]=dis[now]+1;
- q.push(data[i]);
- }
- }
- return dis[t]>0;
- }
- int dfs(int now,int low){
- if(now==t)return low;
- int Low;
- for(int i=head[now];i!=-1;i=nxt[i]){
- if(weight[i]&&dis[data[i]]==dis[now]+1){
- if(Low=dfs(data[i],Min(low,weight[i]))){
- weight[i]-=Low;
- weight[i^1]+=Low;
- return Low;
- }
- }
- }
- return 0;
- }
- int main(){
- freopen(”air.in”,“r”,stdin);
- freopen(”air.out”,“w”,stdout);
- memset(head,-1,sizeof head);
- scanf(”%d%d”,&m,&n);
- // s=1;t=n;
- // for(int i=1;i<=m;i++){
- // int x,y,z;
- // scanf(“%d%d%d”,&x,&y,&z);
- // add(x,y,z);
- // }
- s=100*4;
- t=100*4+1;
- int x,y;
- while(scanf(“%d%d”,&x,&y)!=EOF&&(x!=-1||y!=-1))add(x,y+n-m,1);
- for(int i=m+1;i<=n;i++){
- add(i+n-m,i,1);
- add(i,t,1);
- }
- for(int i=1;i<=m;i++)add(s,i,1);
- int sum=0,flow;
- while(BFS())
- while(flow=dfs(s,INF))sum+=flow;
- if(!sum){
- printf(”No Solution!”);
- return 0;
- }
- printf(”%d\n”,sum);
- for(int i=0;i<cnt;i++){
- if(!weight[i]&&from[i]!=s&&data[i]!=t&&from[i]!=t&&data[i]!=s&&from[i]<data[i]-n+m){
- ANS[++ANSS].a=from[i];
- ANS[ANSS].b=data[i]-n+m;
- }
- }
- sort(ANS+1,ANS+ANSS+1,cmp);
- for(int i=1;i<=ANSS;i++)printf(“%d %d\n”,ANS[i].a,ANS[i].b);
- return 0;
- }