Codeforces Round #583 (Div. 1 + Div. 2, based on Olympiad of Metropolises) D.Treasure Island (dfs)

题目

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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Code92007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值