题目链接: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<<'
';
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
",bfs());
}
return 0;
}