题意:一个矩形中,有n个城市‘*’,‘o’表示空地,现在这n个城市都要覆盖无线,若放置一个基站,
那么它至多可以覆盖本身和相邻的一个城市,求至少放置多少个基站才能使得所有的城市都覆盖无线?
思路:求二分图的最小路径覆盖(无向图)
最小路径覆盖=点数-最大匹配数
注:因为为无向图,每个顶点被算了两次,最大匹配为原本的两倍,
因此此时最小路径覆盖=点数-最大匹配数/2
#include<stdio.h> #include<string.h> int edge[450][450],num,used[510],link[510]; int x[4]={-1,1,0,0},y[4]={0,0,-1,1}; int dfs(int pos) { int i; for(i=0;i<num;i++) if(edge[pos][i]&&!used[i]){ used[i]=1; if(link[i]==-1||dfs(link[i])){ link[i]=pos; return 1; } } return 0; } int main() { char s[45][15]; int n,m,i,j,k,sum,T,c,r,a[45][15]; scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); num=0; for(i=0;i<n;i++){ scanf("%s",s[i]); for(j=0;j<m;j++) if(s[i][j]=='*') a[i][j]=num++; //将城市编号,并计算其总数 } memset(edge,0,sizeof(edge)); for(i=0;i<n;i++) for(j=0;j<m;j++) if(s[i][j]=='*'){ for(k=0;k<4;k++){ r=i+x[k]; c=j+y[k]; if(r>=0&&r<n&&c>=0&&c<m&&s[r][c]=='*') edge[a[i][j]][a[r][c]]=1; //将有关系的城市建边 } } sum=0; memset(link,-1,sizeof(link)); for(i=0;i<num;i++){ memset(used,0,sizeof(used)); sum+=dfs(i); } sum=num-sum/2; printf("%d\n",sum); } return 0; }
poj 3020 Antenna Placement (最小路径覆盖)
原文地址:http://blog.csdn.net/acm_code/article/details/39852201