M. Maze Connect
题目大意
给你一一部图,让你求出最少打破几条边才能使得这个图从任何地方都能出去,其中 / \ 表示方向不同的墙,分别是正45度和逆向45度的墙;
解题思路
比赛的时候忘记了可以采用将这幅图扩大二倍,这样就可以很好的解决这个墙方向不是直线的原因了,然后就是求出这幅图有打多少个联通块就可以了;我这里试求的被环划分的部分,一幅图被N个联通块可以划分N+1部分;
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int M=2200;
char c;
int mp[M][M];
int n,m;
int vis[4][2]={0,1,0,-1,1,0,-1,0};
void make(int x,int y,char c)//这里是将原来的图扩大二倍,0表示可以走 1表示是强
{
if(c=='\\') mp[x-1][y-1]=mp[x][y]=1;//扩大后变成四个点所以墙也就是对角线
else if(c=='/') mp[x-1][y]=mp[x][y-1]=1;
else return;
}
queue<int> qx,qy;
void bfs(int X,int Y)
{
mp[X][Y]=1;
qx.push(X);
qy.push(Y);
while(!qx.empty())
{
int x=qx.front();qx.pop();
int y=qy.front();qy.pop();
for(int i=0;i<4;i++)
{
int xx=x+vis[i][0];
int yy=y+vis[i][1];
if(xx>=0&&xx<=n&&y>=0&y<=m)
{
if(!mp[xx][yy])
{
mp[xx][yy]=1;
qx.push(xx);
qy.push(yy);
}
}
}
}
return;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>c;
make(i*2,j*2,c);
}
}
int ans=-1;//这里设为-1最后就不用减了
n=n*2+1;//将图扩大2倍,这里有个小技巧就是n=n*2+1,这样可以
m=m*2+1;//在搜索的时候将图的最外不是1的点一下子搜完
for(int i=0;i<=n;i++)
{
for(int j=0;j<=m;j++)
{
if(!mp[i][j]){
bfs(i,j);
ans++;
}
}
}
cout<<ans<<"\n";
return 0;
}

博客讨论了M. Maze Connect问题,涉及如何处理具有特定墙方向的图。作者提出通过扩大图的规模来解决墙的方向问题,并通过求联通块的数量来找出使图连通所需的最少边数。文章包含解题思路和代码实现。
525

被折叠的 条评论
为什么被折叠?



