Problem : Antenna Placement
Description : 题意没看懂,但是!看图看懂了,如图所示,每两个相邻的点可以用一个圆片覆盖,没有相邻的点,那么这个点也可以用一个圆片覆盖,现在问你至少需要多少个圆片才能覆盖所有的点。
Solution : 二分图的最小边覆盖,还是那句老话,如果想用二分图做,那么就一点要找到对应的边、点、联系,这题一一对应下来,就是要用最少的边来覆盖所有的点!但是,这个题给我下面一个题提供了建图思路的灵感。
Code(C++) :
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
const int F=40+5;
const int M=F*F;
const int dirx[]={0,0,1,-1};
const int diry[]={1,-1,0,0};
int R,C;
vector<int> edge[M];
char map[F][F];
int index[F][F];
bool used[M];
int belong[M];
bool dfs(int s)
{
for(int i=0;i<edge[s].size();i++){
int end=edge[s].at(i);
if(used[end])
continue;
used[end]=true;
if(belong[end]==-1||dfs(belong[end])){
belong[end]=s;
return true;
}
}
return false;
}
int main()
{
//freopen("in.data","r",stdin);
int N;
cin>>N;
while(N--){
cin>>R>>C;
for(int i=0;i<M;i++)
edge[i].clear();
memset(belong,-1,sizeof(belong));
string tmp;
for(int i=1;i<=R;i++){
cin>>tmp;
for(int j=1;j<=C;j++)
map[i][j]=tmp.at(j-1);
}
int cnt=0;
memset(index,0,sizeof(index));
for(int i=1;i<=R;i++)
for(int j=1;j<=C;j++)
if(map[i][j]=='*')
index[i][j]=++cnt;
for(int i=1;i<=R;i++)
for(int j=1;j<=C;j++)
if(index[i][j])
for(int k=0;k<4;k++){
int tx=i+dirx[k];
int ty=j+diry[k];
if(tx>=1&&tx<=R&&ty>=1&&ty<=C&&index[tx][ty])
edge[index[i][j]].push_back(index[tx][ty]);
}
int sum=0;
for(int i=1;i<=cnt;i++){
memset(used,false,sizeof(used));
if(dfs(i))
++sum;
}
printf("%d\n",cnt-sum/2);
}
return 0;
}