hdu3360-二分图

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3360

Description
略略略……
hdu3360-二分图_第1张图片

Input

Your program will be tested on one or more test cases. Each test case is specified using R+1 lines.
The first line specifies two integers (1<= R,C <= 50) which are the dimensions of the museum hall. The next R lines contain C integers separated by one or more spaces. The j-th integer of the i-th row is -1 if cell (i, j) already contains one of the museum’s guards, otherwise it contains an integer (0 <= T <= 2 12) representing the type of the artifact in that cell.
The last line of the input file has two zeros.

Output
For each test case, print the following line:
k. G
Where k is the test case number (starting at one,) and G is the minimum number of additional guards to hire such that all remaining artifacts are secured.

Sample Input
1 3
512 -1 2048
2 3
512 2560 2048
512 2560 2048
0 0

Sample Output

  1. 0
  2. 2

题意
博物馆大小为n*m,博物馆不为-1的点上有文物,要求所有文物被保护需要的最少护卫。护卫的位置不能在博物馆之外。
文物被保护的定义:这个文物的所有必须被保护的点都要有守卫。 一个文物由一个2的12次方以内的数表示,那么这个数最多有12位,对应图中给出打的12个可能要被保护的点。

思路
把每个文物与之需要保护的点建边,要求所有的边都被覆盖,就是求二分图的最小点覆盖。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define lson l,mid,i<<1
#define rson mid+1,r,i<<1|1
using namespace std;
typedef long long ll;
const int maxn = 3600;
int dx[12] = { -1,-2,-2,-1,1,2,2,1,-1,0,1,0 };
int dy[12] = { -2,-1,1,2,2,1,-1,-2,0,1,0,-1 };
int link[maxn];
int vis[maxn];
vector<int>mp[maxn];
int a[maxn][maxn];
int Nx;
bool dfs(int u) {
for (int i = 0; i < mp[u].size(); i++) {
int v = mp[u][i];
if (!vis[v]) {
vis[v] = 1;
if (link[v] == -1 || dfs(link[v])) {
link[v] = u;
return 1;
}
}
}
return 0;
}
int xyl() {
int ans = 0;
memset(link, -1, sizeof(link));
for (int i = 0; i < Nx; i++) {
memset(vis, 0, sizeof(vis));
if (dfs(i))
ans++;
}
return ans;
}
int main() {
int n, m;
int cnt = 1;
while (scanf("%d%d", &n, &m) != EOF) {
if (n == 0 && m == 0)
break;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
scanf("%d", &a[i][j]);
}
}
for (int i = 0; i < n*m; i++)
mp[i].clear();
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (a[i][j] != -1) {
for (int k = 0; k < 12; k++) {
if ((a[i][j] >> k) & 1) {
int xx = dx[k] + i;
int yy = dy[k] + j;
if (xx >= 0 && xx < n&&yy >= 0 && yy < m&&a[xx][yy] != -1) {
int u = i * m + j;
int v = xx * m + yy;
mp[u].push_back(v);
mp[v].push_back(u);
}
}
}
}
}
}
Nx = n * m;
printf("%d. %d\n", cnt++, xyl() / 2);
}
}

谢谢你请我吃糖果

你可能感兴趣的:(hdu3360-二分图)