洛谷p1902 刺杀大使 dfs+二分

题目:

https://www.luogu.com.cn/problem/P1902

解题思路:

        一开始理解错误题意,以为要找出所有能到达n层m个房间的路线才能进入大使馆。后来发现只要找到一条能达到n层任意一个房间的路线即可进入大使馆,n层房间之间是互通的,达到其中一个就能到达其他任意房间。 

        题目是求最大代价的最小值。 

二分模板 r=mid  check函数要保证mid的最大代价,即路线中的代价都小于等于mid。

dfs求路径:

!!!特别注意:本题目中的dfs不需要恢复现场,否则超时。(注释部分)

对于同一个点,扩展顺序相同,扩展过一次无需再扩展下一次,因为扩展后的路径是固定的,不恢复现场,可有效防止反复无用扩展。同一个点扩展之后不能到达n层,再扩展也不能到达n层。

check函数里面注意flag置零:

完整代码:

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
typedef long long LL;
using namespace std;
const int N = 200010;

int n,m;
int p[1010][1010];
int flagg ;
int flag[1010][1010];
//最大值的最小
int my[4]={0,0,1,-1};
int mx[4]={1,-1,0,0};
void dfs(int x, int y,int maxx){
	
	if( x == n ) {
		flagg = 1 ;
		return ;
	}
	
	for(int i=0;i<4;i++){
		int tx = x + mx[i];
		int ty = y + my[i];
		if(tx < 1 || ty < 1 || ty > m || tx > n || p[tx][ty] > maxx || flag[tx][ty] ) continue ;
		
		flag[tx][ty] = 1;
		dfs(tx,ty,maxx);
//		flag[tx][ty] = 0;
		
		if(flagg) break; 
		
	}
	if(flagg) return ;
}
int check(int x){ //保证x的最大值 
	flagg = 0;
	memset(flag , 0 ,sizeof flag);

	dfs(1,1,x);

	if(flagg) return 1;
	else return 0;
}

int main(){
	cin >> n >> m;
	int rr=-INF;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin >> p[i][j];
			rr = max(rr,p[i][j]);
		}
			
	}
	int ll = 0;
	
	while( ll+1 < rr){
		int mid = ll + rr >> 1;
		if(check(mid))  rr = mid;
		else ll = mid;
//		cout << "***" << mid << " " << check(mid) <<" " << endl;
	} 
	
	cout <<  rr ;
//	cout << check(1);
	
	return 0;
}

  • 14
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值