有一座新建城市,城市的地图是一个 n \times mn×m的网格。城市中有居民区,和非居民区。现在政府想网格边界上建造一些公共设施点,供居民们使用。如果在某条边界上建设了公共设施点,那么以这条边为分界线的两个区域都能使用。如下图,蓝色圈代表公共设施区,红色的区域能用公共设施。
请你帮忙计算,最少要建多少个公共设施点,才能让所有的居民,都有公共设施可用。
输入格式
第一行输入两个整数 n,m (1 \leq n,m \leq 100)n,m(1≤n,m≤100),表示城市的地图大小。
接下来输入一个 n \times mn×m 的矩阵,代表城市的地图信息。‘*‘
表示居民区,‘o‘
表示非居民区。
输出格式
输出最少要建多少个公共设施点,才能满足要求。
样例输入
3 4 o**o *o** o**o
样例输出
4 分析:先求最多两个居民区可建多少个公共设施点,再加上单独的就行了。
#include<iostream> #include<cstring> #include<algorithm> #include<vector> using namespace std; const int maxn=101; int cnt=0; vector<int>map[maxn*maxn]; int num[maxn][maxn],dx[5]={0,1,-1,0,0},dy[5]={0,0,0,1,-1},match[maxn*maxn]; char a[maxn][maxn]; bool book[maxn*maxn]; bool dfs(int s){ book[s]=1; for(int i=0;i<map[s].size();++i){ int v=map[s][i]; if(!match[v]||!book[match[v]]&&dfs(match[v])){ match[v]=s; match[s]=v; return 1; } } return 0; } int main(){ int n,m; cin>>n>>m; for(int i=1;i<=n;++i){ cin>>&a[i][1]; } for(int i=1;i<=n;++i){ for(int j=1;j<=m;++j){ if(a[i][j]==‘*‘){ num[i][j]=++cnt; } } } for(int i=1;i<=n;++i){ for(int j=1;j<=m;++j){ if(num[i][j]>0){ for(int k=1;k<=4;++k){ int x=i+dx[k],y=j+dy[k]; if(x<1||x>n||y<1||y>m||num[x][y]<=0)continue; map[num[i][j]].push_back(num[x][y]); map[num[x][y]].push_back(num[i][j]); } } } } int ans=0; for(int i=1;i<=cnt;++i){ memset(book,0,sizeof(book)); if(match[i]==0&&dfs(i))++ans; } ans+=cnt-2*ans; cout<<ans; return 0; }
时间: 2024-10-10 07:48:30