[题解]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());
}

原文地址:https://www.cnblogs.com/superminivan/p/11454947.html

时间: 2024-10-12 10:24:47

[题解]luogu_P4011_孤岛营救问题(状压bfs/最短路的相关文章

hdu 1429 状压bfs

#include <iostream> #include <cstring> #include <string> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <map> #define inf 0x3f3f3f3f #define ll __in

HDU 5094 状压BFS

给出n*m矩阵 给出k个障碍,两坐标之间存在墙或门,门最多10种, 给出s个钥匙位置及编号,相应的钥匙开相应的门 状压BFS即可,注意有可能同一个位置有多个门或者多个钥匙 #include "stdio.h" #include "string.h" #include "queue" using namespace std; int b[]={1,2,4,8,16,32,64,128,256,512,1024,2048}; int dir[4][2

HDU 4012 Paint on a Wall(状压+bfs)

Paint on a Wall Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)Total Submission(s): 830    Accepted Submission(s): 325 Problem Description Annie wants to paint her wall to an expected pattern. The wall can be repr

POJ 2411【题解】Mondriaan&#39;s Dream 状压DP

题目链接:http://poj.org/problem?id=2411 把每一行当作一个二进制状态. 1表示是一个竖着的1*2的方格. 0表示其他状态. 那么显然当i-1的状态k能转移到i的j: 1.j 和 k 的按位与为0.(有1必须要0,0也可以有1) 2.j 和 k 按位或每一段0都有偶数个.(表示横着的长方形) 那么就可以预处理一下合格的点. 然后状压DP. 代码如下: #include<cstdio> using namespace std; int n,m; long long f

[GDOI2015]推箱子(状压bfs)

[GDOI2015]推箱子(状压bfs) 题面 题面过长,略 分析 观察到$m \times m =64 \(,那么可以把箱子的01状态压到一个```unsigned long long```里面 然后对于地图上的每一个点\)(x,y)\(,预处理出左上角在\)(x,y)\(,边长为\)m\(的正方形的01状态.如果这个状态和箱子的状态按位与的结果为0,那么就说明箱子可以通过. 然后发现这类似一个分层图上的最短路问题,直接BFS即可.状态\)dist[x][y][k]\(表示箱子左上角在\)(x

HDU 3619 优先队列+状压+bfs

Heroes of Might and Magic Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 170    Accepted Submission(s): 74 Problem Description After a very long journey and uncountable number of uphill battles

HDU-5025 2014广州网络赛 Saving Tang Monk 状压+BFS

给出一个N*N的矩阵,开启牢门需要收集齐m种钥匙,且必须收集了前i-1种钥匙才能收集第i种钥匙,最终收集齐了回到关押唐僧的房间拯救唐僧,经过一个'S'的房间时需要额外耗时把蛇打死,蛇最多5条,所以状压一下用优先队列BFS求最小时间即可. #include <iostream> #include <cstdio> #include <cmath> #include <queue> #include <vector> #include <cst

HDU 4771 状压bfs

Stealing Harry Potter's Precious Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1295    Accepted Submission(s): 618 Problem Description Harry Potter has some precious. For example, his invisibl

【网络流24题】 No.14 孤岛营救问题 (分层图最短路)

[题意] 1944 年,特种兵麦克接到国防部的命令,要求立即赶赴太平洋上的一个孤岛, 营救被敌军俘虏的大兵瑞恩. 瑞恩被关押在一个迷宫里, 迷宫地形复杂, 但幸好麦克得到了迷宫的地形图. 迷宫的外形是一个长方形, 其南北方向被划分为 N 行,东西方向被划分为 M 列,于是整个迷宫被划分为 N× M 个单元.每一个单元的位置可用一个有序数对(单元的行号,单元的列号)来表示.南北或东西方向相邻的 2 个单元之间可能互通, 也可能有一扇锁着的门,或者是一堵不可逾越的墙.迷宫中有一些单元存放着钥匙, 并