<题目链接>
题目大意:
一个矩形中,有N个城市’*’,现在这n个城市都要覆盖无线,每放置一个基站,至多可以覆盖相邻的两个城市。问至少放置多少个基站才能使得所有的城市都覆盖无线?
解题分析:
将这n个城市看成二分图中的点集,基站匹配的圆圈看成两个点集之间的连线,要使圆圈圈住所有的点,即该二分图中所有的点都必须有线连接,并且使连接的线段条数最少。自然而然,本题就转化为了二分图的最小路径覆盖问题,用最少的边数,去覆盖所有的点。
二分图的最小路径覆盖 = 顶点数 – 最大匹配数(因为本题是无向的,所以最大匹配数为算出的结果/2)
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; int h,w,vN,vM; ][]; ][],vis[],match[],cnt[][]; bool dfs(int x){ ;i<=vM;i++){ if(g[x][i]&&!vis[i]){ vis[i]=; ||dfs(match[i])){ match[i]=x; return true; } } } return false; } int Hungary(){ ; memset(match,-,sizeof(match)); ;i<=vN;i++){ memset(vis,,sizeof(vis)); if(dfs(i))res++; } return res; } int main(){ int T;scanf("%d",&T); while(T--){ scanf("%d%d",&h,&w); ; ;i<=h;i++){ scanf(); ;j<=w;j++) if(mpa[i][j]=='*')cnt[i][j]=++pos; } //与周围四个方向的'*'建立匹配关系 memset(g,,sizeof(g)); ;i<=h;i++){ ;j<=w;j++){ if(mpa[i][j]!='*')continue; >=&&mpa[i-][j]==][j]]=; >=&&mpa[i][j-]==]]=; <=h&&mpa[i+][j]==][j]]=; <=w&&mpa[i][j+]==]]=; } } vN=vM=pos; int ans=Hungary(); printf(); //ans/2为最大匹配数,pos-ans/2为最小路径覆盖数 } }
2018-11-14