[题解]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/最短路的主要内容,如果未能解决你的问题,请参考以下文章