迷宫2 NC15196

题目链接:https://ac.nowcoder.com/acm/problem/collection/541

题意:

从左上角走到右下角,蜥蜴可向八个方位爬行,问使蜥蜴无法到达终点的最小代价

思路

模拟一下得到:如果第一列除(1,1)以外的数或第n行除(n,m)以外的点可以到达第一行或第m列,找到符合条件的最小代价。因为蜥蜴是八个方位行走的,所以我们需要四个方向行走,堵住斜着行走的路。bfs()+优先队列。

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
ll q,n,m;
ll mp[505][505],vis[505][505];
ll d[4][2]={1,0,-1,0,0,1,0,-1};

struct node{
	ll x,y,w;
	friend bool operator < (node a,node b){//优先队列
		return a.w>b.w;
	}
};

bool check(ll x,ll y){
	if(x<1||x>n) return 0;
	if(y<1||y>m) return 0;
	if(vis[x][y] || mp[x][y]==-1) return 0;
	return 1;
}

ll bfs(){
//	memset(vis,0,sizeof(vis));
	priority_queue<node>q;
	for(ll i=2;i<=n;i++)//第一列的点
		if(mp[i][1]!=-1){
			q.push({i,1,mp[i][1]});
			vis[i][1]=1; 
		}	
	for(ll i=2;i<m;i++)//第n行的点
		if(mp[n][i]!=-1){
			q.push({n,i,mp[n][i]});
			vis[n][i]=1; 
		}
	while(!q.empty()){//bfs()
		node p=q.top();q.pop();
//		cout<<p.w<<' '<<p.x<<' '<<p.y<<'\n';
		if(p.x==1||p.y==m){
			return p.w;
		}
		for(ll i=0;i<4;i++){
			ll dx=p.x+d[i][0],dy=p.y+d[i][1];
			if(check(dx,dy)){
				vis[dx][dy]=1;
				q.push({dx,dy,p.w+mp[dx][dy]});
			}
		}
	}
	return -1;
}

int main(){
	scanf("%lld %lld %lld",&q,&n,&m);
	while(q--){
		for(int i=1;i<=n;i++){//不要用memset,会超时
			for(int j=1;j<=m;j++) mp[i][j]=vis[i][j]=0;
		}
		for(ll i=1;i<=n;i++){
			for(ll j=1;j<=m;j++){
				scanf("%lld",&mp[i][j]);
				if(mp[i][j]==0) mp[i][j]=-1;
				else if(mp[i][j]==-1) mp[i][j]=0;
			}
		}
		printf("%lld\n",bfs());
	}
	
	return 0;
} 

猜你喜欢

转载自www.cnblogs.com/voids5/p/12969055.html
nc