[CODEVS1222] 信与信封问题

时间限制: 1 s
空间限制: 128000 KB
题目等级 : 钻石 Diamond
 
题目描述 Description

John先生晚上写了n封信,并相应地写了n个信封将信装好,准备寄出。但是,第二天John的儿子Small John将这n封信都拿出了信封。不幸的是,Small John无法将拿出的信正确地装回信封中了。

将Small John所提供的n封信依次编号为12,…,n;且n个信封也依次编号为12,…,n。假定Small John能提供一组信息:第i封信肯定不是装在信封j中。请编程帮助Small John,尽可能多地将信正确地装回信封。

输入描述 Input Description

n文件的第一行是一个整数nn100)。信和信封依次编号为12,…,n

n接下来的各行中每行有2个数ij,表示第i封信肯定不是装在第j个信封中。文件最后一行是20,表示结束。

输出描述 Output Description

输出文件的各行中每行有2个数ij,表示第i封信肯定是装在第j个信封中。请按信的编号i从小到大顺序输出。若不能确定正确装入信封的任何信件,则输出“none”。

样例输入 Sample Input

3

1  2

1  3

2  1

0  0

样例输出 Sample Output

1   1

 

 
提交地址CODEVS1222
 

 
题解:
我们先跑一遍匈牙利,找出最大匹配, 如果匹配数量和n不同的话, 直接输出none;
然后我们对于每一条连着的边, 如果它是必须的,那么去掉它之后一定不能形成完美匹配;
然后都去一边,不行就输出;
 

 
Code
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring> 
 4 using namespace std;
 5 
 6 int n;
 7 bool del[110][110];
 8 bool vis[110];
 9 int line[110], lik[110];
10 int ans;
11 
12 inline bool dfs(int x)
13 {
14     for (register int i = 1 ; i <= n ; i ++)
15     {
16         if (vis[i] or del[x][i]) continue;
17         vis[i] = 1;
18         if (!line[i] or dfs(line[i]))
19         {
20             line[i] = x;
21             lik[x] = i;
22             return 1;
23         }
24     }
25     return 0;
26 }
27 
28 int main()
29 {
30     cin >> n;
31     int a, b;
32     while (scanf("%d%d", &a, &b) != EOF)
33     {
34         if (a == 0 and b == 0) break;
35         del[a][b] = 1;
36     }
37     for (register int i = 1 ; i <= n ; i ++)
38     {
39         memset(vis, 0, sizeof vis);
40         ans += dfs(i);
41     }
42     if (ans != n) {puts("none");return 0;}
43     bool fl = 0;
44     for (register int i = 1 ; i <= n ; i ++)
45     {
46         int t = lik[i];
47         del[i][t] = 1;
48         lik[i] = 0, line[t] = 0;
49         memset(vis, 0, sizeof vis);
50         if (!dfs(i))
51         {
52             printf("%d %d\n", i, t);
53             line[t] = i, lik[i] = t;
54             fl = 1;
55         }
56         del[i][t] = 0;
57     }
58     if (!fl) {puts("none");return 0;};
59     return 0;
60 }

猜你喜欢

转载自www.cnblogs.com/zZh-Brim/p/9155602.html