二分匹配 飞行员配对方案问题


Time Limit: 1000 ms    Memory Limit: 65535 kB   
Judge type: Multi-cases Special Judge (Detailed Mode - 11 cases)
Total Submit : 487 (156 users)   Accepted Submit : 221 (142 users)   Page View : 4893 
Font Style: Aa Aa Aa
第二次世界大战时期, 英国皇家空军从沦陷国征募了大量外籍飞行员。由皇家空军派出
的每一架飞机都需要配备在航行技能和语言上能互相配合的2 名飞行员, 其中1 名是英国飞
行员,另1名是外籍飞行员。在众多的飞行员中,每一名外籍飞行员都可以与其他若干名英
国飞行员很好地配合。 如何选择配对飞行的飞行员才能使一次派出最多的飞机。对于给定的
外籍飞行员与英国飞行员的配合情况,试设计一个算法找出最佳飞行员配对方案,使皇家空
军一次能派出最多的飞机。 
编程任务: 
对于给定的外籍飞行员与英国飞行员的配合情况,编程找出一个最佳飞行员配对方案,
使皇家空军一次能派出最多的飞机。

Input

第1 行有 2个正整数m和 n。n是皇家空军的飞行
员总数(n<100);m是外籍飞行员数。外籍飞行员编号为 1~m;英国飞行员编号为 m+1~n。
接下来每行有2个正整数i和j,表示外籍飞行员i可以和英国飞行员j配合。文件最后以 2
个-1 结束。

Output

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

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

Source

直接用匈牙利算法找最大匹配。
代码
 1 #include<cstdio>
 2 #include<cstring>
 3 #define maxn 100
 4 using namespace std;
 5 int nx,sum;
 6 int edge[maxn][maxn];     //edge[i][j]表示i与j能够匹配
 7 int cx[maxn],cy[maxn];    //用来记录cx集合中匹配cy中得哪个元素,cy匹配cx中的哪个元素
 8 int visited[maxn];        //用来记录该顶点是否被访问过
 9 int path(int u)
10 {
11     int v;
12     for(v=nx+1;v<=sum;v++)
13     {
14         if(edge[u][v]&&!visited[v])
15         {
16             visited[v]=1;
17             if(cy[v]==-1||path(cy[v]))   //如果y集合中的v元素没有匹配或者是v已经匹配,但是从cy[v]中能够找到一条增广路
18             {
19                 cx[u]=v;                //记录cx[u]匹配的对象
20                 cy[v]=u;
21                 return 1;
22             }
23         }
24     }
25     return 0;
26 }
27 int maxmatch()
28 {
29     int res=0;
30     memset(cx,0xff,sizeof(cx));
31     memset(cy,0xff,sizeof(cy));
32     for(int i=1;i<=nx;i++)
33     {
34         if(cx[i]==-1)
35         {
36             memset(visited,0,sizeof(visited));
37             res+=path(i);
38         }
39     }
40     return res;
41 }
42 int main()
43 {
44     int s,t;
45     while(scanf("%d%d",&nx,&sum)!=EOF)
46     {
47         memset(edge,0,sizeof(edge));
48         while(scanf("%d%d",&s,&t)!=EOF&&s!=-1&&t!=-1)
49         {
50             edge[s][t]=1;
51         }
52         if(!maxmatch()) printf("No Solution!\n");
53         else
54         {
55             printf("%d\n",maxmatch());
56             for(int i=1;i<=nx;i++)
57             {
58                 if(cx[i]!=-1)
59                 {
60                     printf("%d %d\n",i,cx[i]);
61                 }
62             }
63         }
64     }
65     return 0;
66 }

 

posted @ 2013-08-16 20:07  ゐ星落★孤晨ね  阅读(219)  评论(0编辑  收藏  举报