「网络流 24 题」孤岛营救问题 最短路

版权声明:本博客内容基本为原创,如有问题欢迎联系,转载请注明出处 https://blog.csdn.net/qq_41955236/article/details/83478879

题目链接:https://loj.ac/problem/6121

题意:

        给你一个n*m的图,你要从(1,1)出发到达(n,m),路上会有最多p种墙和钥匙。接下来会给你k个门,在x1,y1,x2,y2之间会有一扇ki类型的门,如果ki为0,那么无法穿过,否则你要拿到对应ki的钥匙才可以穿过,同理接下来会有s把钥匙,这些钥匙在xi,yi处,类型为ki。,每走一步需要1的时间,现在问你从起点到终点最少需要多少时间。

做法:

       好像做到过很多次了这种题目,因为题目的数据范围很小,所以不需要太多的优化,直接做就好了,只是最短路在处理的时候加上一个状态这个量就好了,因为钥匙和门的对应种类最多只有10,完全可以状压成状态,01代表这个钥匙是否被拿过,dp这个的时候也要加上状态的量,然后用优先队列减少宽搜时间,到达之后就可以直接break掉。

       不过这题有个坑点,就是一个格子种可能会有多把钥匙,没看清这个条件wa了好几次。难受巴巴。


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int n,m,p,mp[150][150],k,dp[15][15][4000],key[15][15],ans;
struct node{
    int x,y,step,state;
    node(){}
    node(int x,int y,int step,int state):x(x),y(y),step(step),state(state){}
    bool operator < (const node &a) const {
        return step>a.step;
    }
};
int gain(int x,int y){
    return m*(x-1)+y;
}
int ck(int state,int x,int y,int tx,int ty){
    int a=gain(x,y),b=gain(tx,ty);
    if(x<1||x>n||y<1||y>m||mp[a][b]==0) return 0;
    if(mp[a][b]==-1) return 1;
    else {
        int now=mp[a][b];
        if(state&(1<<(now-1))) return 1;
        return 0;
    }
}
void bfs(){
    priority_queue<node> q;
    dp[1][1][0]=0;
    q.push(node(1,1,0,0));
    while(!q.empty()){
        node u=q.top(); q.pop();
        if(u.x==n&&u.y==m){
            ans=u.step;
            break;
        }
        for(int i=0;i<4;i++){
            int dx=u.x+dir[i][0],dy=u.y+dir[i][1];
            if(ck(u.state,dx,dy,u.x,u.y)){
                if(key[dx][dy]!=-1){
                    int now=key[dx][dy];
                    int nextstate=u.state|now;
                    if(dp[dx][dy][nextstate]>dp[u.x][u.y][u.state]+1){
                        dp[dx][dy][nextstate]=dp[u.x][u.y][u.state]+1;
                        q.push(node(dx,dy,u.step+1,nextstate));
                    }
                }
                else {
                    if(dp[dx][dy][u.state]>dp[u.x][u.y][u.state]+1){
                        dp[dx][dy][u.state]=dp[u.x][u.y][u.state]+1;
                        q.push(node(dx,dy,u.step+1,u.state));
                    }
                }
            }
        }
    }
}
int main(){
    ans=-1;
    memset(dp,125,sizeof(dp));
    memset(mp,-1,sizeof(mp));
    memset(key,-1,sizeof(key));
    scanf("%d%d%d%d",&n,&m,&p,&k);
    for(int i=1;i<=k;i++){
        int a,b,c,d,g;
        scanf("%d%d%d%d%d",&a,&b,&c,&d,&g);
        int x=gain(a,b),y=gain(c,d);
        mp[x][y]=mp[y][x]=g;
    }
    scanf("%d",&k);
    for(int i=1;i<=k;i++){
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        if(key[x][y]==-1) key[x][y]=0;
        key[x][y]|=(1<<(z-1));
    }
    bfs();
    printf("%d\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41955236/article/details/83478879