HDU 1498:50 years, 50 colors(二分图匹配)

http://acm.hdu.edu.cn/showproblem.php?pid=1498

题意:给出一个 n*n 的矩阵,里面的数字代表一种颜色,每次能炸掉一排或者一列的相同颜色的气球,问有哪些颜色的气球不能在 k 次内炸完的,从小到大输出,能炸完输出-1.

思路:先存下点,用一个数字标记颜色是否出现过,然后遍历每一种颜色,再把这种颜色的行号和列号连边,跑一遍匈牙利,如果得到的结果大于 k 那么这种颜色就不行。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 #include <cstdlib>
 5 #include <algorithm>
 6 #include <string>
 7 #include <iostream>
 8 #include <stack>
 9 #include <map>
10 #include <queue>
11 using namespace std;
12 #define N 100010
13 #define INF 0x3f3f3f3f
14 struct node
15 {
16     int nxt, v;
17 }edge[105*105];
18 int mp[105][105];
19 int head[105], tot;
20 bool vis[105], col[105];
21 int ans[105];
22 int match[105], n, k;
23 
24 void add(int u, int v)
25 {
26     edge[tot].v = v; edge[tot].nxt = head[u]; head[u] = tot++;
27 }
28 
29 bool dfs(int u)
30 {
31     for(int i = head[u]; ~i; i = edge[i].nxt) {
32         int v = edge[i].v;
33         if(!vis[v]) {
34             vis[v] = 1;
35             if(match[v] == -1 || dfs(match[v])) {
36                 match[v] = u;
37                 return true;
38             }
39         }
40     }
41     return false;
42 }
43 
44 int main()
45 {
46     while(scanf("%d%d", &n, &k), n + k) {
47         memset(mp, 0, sizeof(mp));
48         memset(col, 0, sizeof(col));
49         for(int i = 1; i <= n; i++) {
50             for(int j = 1; j <= n; j++) {
51                 scanf("%d", &mp[i][j]);
52                 col[mp[i][j]] = 1;
53             }
54         }
55         int l = 0;
56         for(int i = 1; i <= 50; i++) {
57             if(col[i]) {
58                 tot = 0;
59                 memset(head, -1, sizeof(head));
60                 for(int j = 1; j <= n; j++) {
61                     for(int k = 1; k <= n; k++) {
62                         if(mp[j][k] == i) {
63                             add(j, k);
64                         }
65                     }
66                 }
67                 memset(match, -1, sizeof(match));
68                 int tmp = 0;
69                 for(int j = 1; j <= n; j++) {
70                     memset(vis, 0, sizeof(vis));
71                     if(dfs(j)) tmp++;
72                 }
73                 if(tmp > k) ans[l++] = i;
74             }
75         }
76 //        printf("ans : ");
77         for(int i = 0; i < l; i++) {
78             if(i != l - 1) printf("%d ", ans[i]);
79             else printf("%d
", ans[i]);
80         }
81         if(l == 0) printf("-1
");
82     }
83     return 0;
84 }
原文地址:https://www.cnblogs.com/fightfordream/p/6042795.html