[题解]luogu_P4011_孤岛营救问题(状压bfs/最短路

Posted superminivan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[题解]luogu_P4011_孤岛营救问题(状压bfs/最短路相关的知识,希望对你有一定的参考价值。

钥匙只有10种可以状压,最短路或者bfs都行,但是写挂了(现在还是

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define pb push_back
using namespace std;
const int maxn=13;
const int dx[]=-1,0,1,0;
const int dy[]=0,1,0,-1;
int n,m,p,k,s;
//int e[maxn][maxn][4];
int e[maxn][maxn][maxn][maxn];
//vector<int>key[maxn][maxn];
int key[maxn][maxn];
bool v[maxn][maxn][1<<13];
int d[maxn][maxn][1<<13];
struct node
    int x,y,key,d;
    node()
    node(int xx,int yy,int k,int dd)
        x=xx,y=yy,key=k,d=dd;
    
    bool operator <(const node&a)const
        return d>a.d;
    
;
//priority_queue<node>q;

//inline int hsh(int x,int y)
//    int kk=0;
//    for(int i=0;i<key[x][y].size();i++)
//    kk|=(1<<key[x][y][i]-1);
//
//void dij()
//    memset(d,0x7f,sizeof(d));
////    int kk=hsh(1,1);
////    for(int i=0;i<key[1][1].size();i++)
////    kk|=(1<<key[1][1][i]-1);
//    int kk=key[1][1];
//    d[1][1][kk]=0;
//    q.push(node(1,1,kk,0));
//    while(!q.empty())
//        int x=q.top().x,y=q.top().y,k=q.top().key;q.pop();
//        if(v[x][y][k])continue;
//        v[x][y][k]=1;
//        for(int i=0;i<4;i++)
//            int xx=x+dx[i],yy=y+dy[i];
//            if(e[x][y][xx][yy]==-1)continue;
//            if(xx<1 || xx>n || yy<1 || yy>m)continue;
//            if(e[x][y][xx][yy] && !(k&(1<<e[x][y][xx][yy]-1)))continue;
//            int kk=k;
////            for(int j=0;j<key[xx][yy].size();j++)
////            kk|=(1<<key[xx][yy][j]-1);
//            kk|=key[xx][yy];
//            if(d[xx][yy][kk]>d[x][y][k]+1)
//                d[xx][yy][kk]>d[x][y][k]+1;
//                q.push(node(xx,yy,kk,d[xx][yy][kk]));
//            
//        
//    
//
queue<node>q;
int bfs()
    q.push(node(1,1,key[1][1],0));
    v[1][1][key[1][1]]=1;
    while(!q.empty())
        node t=q.front();q.pop();
        if(t.x==n&&t.y==m)return t.d;
        int x=t.x,y=t.y;
        for(int i=0;i<4;i++)
            int xx=x+dx[i],yy=y+dy[i],opt=e[x][y][xx][yy];
            if(xx<1||xx>n||yy<1||yy>m||(opt&&!(k&(1<<opt-1))))continue;
            int kk=t.key|key[xx][yy];
            if(v[xx][yy][kk])continue;
            q.push(node(xx,yy,kk,t.d+1)),v[xx][yy][kk]=1;
        
    
    return -1;

int main()
    scanf("%d%d%d",&n,&m,&p);
    scanf("%d",&k);
    for(int i=1,x1,y1,x2,y2,g,p;i<=k;i++)
        scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&g);
        if(g==0)g=-1;
//        if(x1==x2)p=(y1-y2==1?3:1);
//        if(y1==y2)p=(x1-x2==1?0:4);
//        e[x1][y1][p]=g;
//        e[x2][y2][4-p]=g;
        e[x1][y1][x2][y2]=g;
        e[x2][y2][x1][y1]=g;
    
    scanf("%d",&s);
    for(int i=1,x,y,q;i<=s;i++)
        scanf("%d%d%d",&x,&y,&q);
//        key[x][y].pb(q);
        key[x][y]|=(1<<q);
    
//    dij();
//    int ans=0x7f7f7f7f;
//    for(int i=0;i<=(1<<p);i++)ans=min(ans,d[n][m][i]);
//    if(ans!=0x7f7f7f7f)printf("%d",ans);
//    else printf("-1");
    
    printf("%d",bfs());

 

以上是关于[题解]luogu_P4011_孤岛营救问题(状压bfs/最短路的主要内容,如果未能解决你的问题,请参考以下文章

洛谷 P4011 孤岛营救问题bfs

网络流24题14孤岛营救问题

孤岛营救问题

网络流24题----14孤岛营救问题

网络流 24 题 解题报告

网络流 24 题 解题报告