题目链接:http://poj.org/problem?id=3020
The Global Aerial Research Centre has been allotted the task of building the fifth generation of mobile phone nets in Sweden. The most striking reason why they got the job, is their discovery of a new, highly noise resistant, antenna. It is called 4DAir, and comes in four types. Each type can only transmit and receive signals in a direction aligned with a (slightly skewed) latitudinal and longitudinal grid, because of the interacting electromagnetic field of the earth. The four types correspond to antennas operating in the directions north, west, south, and east, respectively. Below is an example picture of places of interest, depicted by twelve small rings, and nine 4DAir antennas depicted by ellipses covering them.
Obviously, it is desirable to use as few antennas as possible, but still provide coverage for each place of interest. We model the problem as follows: Let A be a rectangular matrix describing the surface of Sweden, where an entry of A either is a point of interest, which must be covered by at least one antenna, or empty space. Antennas can only be positioned at an entry in A. When an antenna is placed at row r and column c, this entry is considered covered, but also one of the neighbouring entries (c+1,r),(c,r+1),(c-1,r), or (c,r-1), is covered depending on the type chosen for this particular antenna. What is the least number of antennas for which there exists a placement in A such that all points of interest are covered?
Input
On the first row of input is a single positive integer n, specifying the number of scenarios that follow. Each scenario begins with a row containing two positive integers h and w, with 1 <= h <= 40 and 0 < w <= 10. Thereafter is a matrix presented, describing the points of interest in Sweden in the form of h lines, each containing w characters from the set ['*','o']. A '*'-character symbolises a point of interest, whereas a 'o'-character represents open space.
Output
For each scenario, output the minimum number of antennas necessary to cover all '*'-entries in the scenario's matrix, on a row of its own.
Sample Input
2
7 9
ooo**oooo
**oo*ooo*
o*oo**o**
ooooooooo
*******oo
o*o*oo*oo
*******oo
10 1
*
*
*
o
*
*
*
*
*
*
Sample Output
17
5
全球航空研究中心被分配在瑞典建造第五代移动电话网的任务。他们得到这份工作的最显著原因是他们发现了一种新的、高抗噪音的天线。它被称为 4DAir,有四种类型。由于地球的相互作用电磁场,每种类型只能以与(略偏斜)纬度和纵向网格对齐的方向发送和接收信号。这四种类型对应于分别向北、西、南和东方向运行的天线。下面是一个名胜古迹的示例图片,由 12 个小环和 9 个 4DAir 天线(由覆盖它们的椭圆)描绘。
显然,最好使用尽可能少的天线,但仍为每个感兴趣的地方提供
覆盖。我们对问题建模如下:让 A 成为描述瑞典表面的矩形矩阵,其中 A 的条目是兴趣点,必须至少由一个天线或空白空间覆盖。天线只能定位在 A 中的条目上。当天线放置在 r 行和列 c 时,此条目被视为已覆盖,但根据为此特定天线选择的类型,还包括一个相邻条目(c+1、r)、(c-1、r_1)、(c-1、r 或 (c,r-1)。A 中存在放置位置的天线数量最少,以便涵盖所有兴趣点的数量是多少?
输入
输入的第一行是单个正整数 n,指定随后的方案数。每个方案以包含两个正整数 h 和 w 的行开始,其中 1 <= h <= 40 和 0 <w <= 10。之后,给出了一个矩阵,以 h 行的形式描述瑞典的兴趣点,每个行都包含集中的 w 字符 [''','o'。"*"字符表示兴趣点,而"o"字符表示开放空间。
输出
对于每个方案,输出覆盖方案矩阵中所有"+"条目所需的最小天线数。"
这个题要建图和上个题一样,唯一变的地方在于输出结果变了,注意题目要求的是涵盖所有兴趣点的最少边,即最小边覆盖,而且最小边覆盖=节点数n-最大匹配数,证明略,因为这里是无向图,所以记得要除2.
#include <iostream>
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
vector<int> G[1000];
int visited[500],nxt[500];
char str[50][50];
int a[50][50];
int dir[4][2]={{0,1},{0,-1},{-1,0},{1,0}};
int n,m,cnt;
int find(int x){
for(int i = 0;i<G[x].size();++i){
int v = G[x][i];
if(!visited[v]){
visited[v]=1;
if(nxt[v]==-1||find(nxt[v])){
nxt[v]=x;
return 1;
}
}
}
return 0;
}
int match(){
memset(nxt,-1,sizeof(nxt));
int ans=0;
for(int i = 0;i<cnt;++i){
memset(visited,0,sizeof(visited));
if(find(i)) ans++;
}
return ans;
}
int main(int argc, char** argv) {
int ncase;
scanf("%d",&ncase);
while(ncase--){
for(int i = 0;i<=1000;++i) G[i].clear();
scanf("%d%d",&n,&m);
for(int i = 0;i<n;++i) scanf("%s",str[i]);
cnt=0;
for(int i = 0;i<n;++i)
for(int j = 0;j<m;++j)
if(str[i][j]=='*')
a[i][j]=cnt++;
// for(int i = 0;i<n;++i){
// for(int j = 0;j<m;++j){
// printf("%d ",a[i][j]);
// }
// printf("\n");
// }
for(int i = 0;i<n;++i){
for(int j=0;j<m;++j){
if(str[i][j]=='o') continue;
int u = a[i][j];
for(int k = 0;k<4;++k){
int x=i+dir[k][0];
int y=j+dir[k][1];
if(x>=0&&x<n&&y>=0&&y<m&&str[x][y]=='*'){
int v=a[x][y];
G[u].push_back(v);
G[v].push_back(u);
}
}
}
}
printf("%d\n",(cnt*2-match())/2);
}
return 0;
}
有关二分图匹配的知识和资料可以参考我的这篇文章:https://blog.youkuaiyun.com/qq_43472263/article/details/96831025