题目
n*m(3<=n*m<=1e6)的网格图,有一些是'.'一些是'#','#'是障碍物'.'是空地
保证(0,0)和(n-1,m-1)不是‘#’,
现在从(0,0)出发,只能向右或向下走,
现给出一张图,问最少把多少个.改成#,
才能使从(0,0)出发,无论怎么走也到不了(n-1,m-1)
思路来源
https://blog.csdn.net/weixin_43464149/article/details/100550596
题解
堵上(0,1)和(1,0),说明最大答案是2,
把#标成已访问,每次只能走未访问的点,
从(0,0)开始dfs,如果(n-1,m-1)不可达,答案是0
如果找到一条路径,标记这条路径,重新dfs
如果能找到另一条不相交路径,说明源到汇有至少两条不相交路径答案是2,
否则,说明所有路径必经一个关键点,答案是1
代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n,m;
bool ok;
vector<int>E[N];
bool vis[N];
char s[N];
int f(int x,int y)
{
return x*m+y;
}
//构建两条不相交路径
//找到一条路径 并沿途标记
void dfs(int x,int y)
{
if(ok)return;
vis[f(x,y)]=1;
if(x==n-1&&y==m-1)
{
ok=1;
return;
}
if(x+1<n&&!vis[f(x+1,y)])dfs(x+1,y);
if(y+1<m&&!vis[f(x,y+1)])dfs(x,y+1);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;++i)
{
scanf("%s",s);
for(int j=0;j<m;++j)
{
if(s[j]=='#')
{
vis[f(i,j)]=1;
}
}
}
dfs(0,0);
if(!ok)puts("0");
else
{
ok=0;
vis[f(0,0)]=0;
vis[f(n-1,m-1)]=0;
dfs(0,0);
if(!ok)puts("1");
else puts("2");
}
return 0;
}