发布于 

Antenna Placement

Antenna Placement

POJ 3020

题目来源: POJ

分析

题目给出一个$ n m $的由*o组成的图,要求用一些宽度为1,长度为2的板子将所有的*覆盖。要求求出最少需要多少板子。

我们假设若两个*相邻,那么它们之间便有一条边。那么我们可以看到,对于任意一个点,与其相邻的任意两个点之间一定不存在边。所以由此构造出来的图满足二分图的性质。而这个问题明显的转化为了一个二分图的最小点覆盖问题。所以我们直接套用匈牙利算法即可。

代码

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
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

char mp[50][20];
bool flag[50][20];
int belong[50][20][2];
int n,m;

bool inmp(int x,int y)
{
return x>=0 && x<n && y>=0 && y<m;
}

const int xp[] = {0,0,-1,1};
const int yp[] = {1,-1,0,0};
bool find(int x, int y)
{
for (int i = 0; i<4; i++)
if (inmp(x+xp[i],y+yp[i]) && mp[x+xp[i]][y+yp[i]]=='*' && !flag[x+xp[i]][y+yp[i]])
{
flag[x+xp[i]][y+yp[i]] = true;
if (belong[ x+xp[i] ][ y+yp[i] ][0]==-1 || find( belong[ x+xp[i] ][ y+yp[i] ][0], belong[ x+xp[i] ][ y+yp[i] ][1]) )
{
belong[ x+xp[i] ][ y+yp[i] ][0] = x;
belong[ x+xp[i] ][ y+yp[i] ][1] = y;
return true;
}
}
return false;
}

int main()
{
int T;
cin >> T;
while (T--)
{
memset(belong,-1,sizeof(belong));

cin >> n >> m;

int num = 0;
for (int i = 0; i<n; i++)
for (int j = 0; j<m; j++)
{
cin >> mp[i][j];
if (mp[i][j]=='*')
num++;
}

int cnt = 0;
for (int i = 0; i<n; i++)
for (int j = 0; j<m; j++)
if (mp[i][j]=='*')
{
memset(flag,false,sizeof(flag));
if (find(i,j))
cnt ++;
}

cout << num - cnt/2 << endl;
}
}

本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

本站由 [@Songer](https://blog.songer.xyz/) 创建,使用 Stellar 作为主题。