标签:style blog strong os 2014 for
题意:
一个矩形中,有N个城市’*’,现在这n个城市都要覆盖无线,若放置一个基站,那么它至多可以覆盖相邻的两个城市。
问至少放置多少个基站才能使得所有的城市都覆盖无线?
思路:
二分图难的不是它的代码多难,而是它该怎么建立。像本题,初看好像与二分图无关,但是我们稍微转化一下,就发现,这就是一个二分图的问题了
首先,我们可以从第一个*,也就是城市开始标记。例如:
*** 标记为:123
oo* oo4
**o 56o
然后,我们就把123456分别存在v1 v2 中,所以对于3,它的匹配点为2、4,这时可以把32,34标记
剩下的就是基本的二分图思想了;
AC代码:
#include<iostream> #include<string.h> using namespace std; int link[405][405]; //关系 int city[45][15]; //记录城市的位置 int vis[405],col[405]; //不解释! int h,w,v1,v2,m,tot; int dir[4][2]={1,0,-1,0,0,-1,0,1}; int dfs(int x) { for(int i=1;i<=v2;i++) { if(!vis[i]&&link[x][i]) { vis[i]=1; if(col[i]==0||dfs(col[i])) { col[i]=x; return 1; } } } return 0; } int main() { int n,i,j; cin>>n; while(n--) { m=0; tot=0; memset(link,0,sizeof(link)); memset(city,0,sizeof(city)); memset(col,0,sizeof(col)); cin>>h>>w; char c; for(i=1;i<=h;i++) for(j=1;j<=w;j++) { cin>>c; if(c=='*'){ tot+=1; city[i][j]=tot; } } for(i=1;i<=h;i++) for(j=1;j<=w;j++) if(city[i][j]){ for(int k=0;k<4;k++){ //向四个方向找与当前位置匹配的点 int x=i+dir[k][0]; int y=j+dir[k][1]; if(city[x][y]) link[city[i][j]][city[x][y]]=1; } } v1=v2=tot; // cout<<tot<<endl; for(i=1;i<=v1;i++) { memset(vis,0,sizeof(vis)); if(dfs(i)) m++; } // cout<<m<<endl; cout<<tot-m/2<<endl; //为什么是这个自己想 } return 0; }
POJ 3020 Antenna Placement,布布扣,bubuko.com
标签:style blog strong os 2014 for
原文地址:http://blog.csdn.net/u012313382/article/details/37697241