[网络流24题]孤岛营救问题

分析

网络流24题总结

这题直接状压BFS也可以,不过可以把BFS改成SPFA,进一步优化

显然要维护三个状态:s,x,y,分别表示钥匙状态s(用一个二进制表示,第i位为1表示当前有第i个钥匙),和当前的x,y坐标,以这三个状态来分层

那么设dist(s,x,y)表示到达当前状态的最短时间

转移就跟BFS的转移一样,除了判断条件里要加关于dist的判断,详见代码

代码

最短路:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<bitset>
#define maxn 15
#define INF 0x3f3f3f3f
using namespace std;
struct node{
    int x;
    int y;
    int k;
    node(){
        
    }
    node(int xx,int yy,int key){
        x=xx;
        y=yy;
        k=key;
    }
};
int n,m,p,k,s; 
int dist[2505][maxn][maxn];
int inq[2505][maxn][maxn];
int key[maxn][maxn];
int door[maxn][maxn][maxn][maxn];
const int walkx[4]={1,-1,0,0};
const int walky[4]={0,0,1,-1};
int spfa(){
    queue<node>q;
    q.push(node(1,1,key[1][1]));
    inq[key[1][1]][1][1]=1;
    memset(dist,0x3f,sizeof(dist)); 
    dist[key[1][1]][1][1]=0;
    while(!q.empty()){
        node now=q.front();
        q.pop();
        inq[now.k][now.x][now.y]=0;
        for(int i=0;i<4;i++){
            int x=now.x+walkx[i];
            int y=now.y+walky[i];
            if(x>=1&&x<=n&&y>=1&&y<=m){ 
                if((door[now.x][now.y][x][y]>=1 && (now.k & (1<<door[now.x][now.y][x][y])) !=0)||door[now.x][now.y][x][y]==-1){
                    if(dist[now.k|key[x][y]][x][y]>dist[now.k][now.x][now.y]+1){
                        dist[now.k|key[x][y]][x][y]=dist[now.k][now.x][now.y]+1;
                        if(!inq[now.k|key[x][y]][x][y]){
                            inq[now.k|key[x][y]][x][y]=1;
                            q.push(node(x,y,now.k|key[x][y]));
                        } 
                    } 
                }
            } 
        }
    }
    int ans=INF;
    for(int i=0;i<(1<<(p+1));i++){
        ans=min(ans,dist[i][n][m]);
    }
    if(ans==INF) return -1;
    else return ans;
}

int main(){
    int x1,y1,x2,y2,g;
    scanf("%d %d %d",&n,&m,&p);
    scanf("%d",&k);
    memset(door,0xff,sizeof(door));
    for(int i=1;i<=k;i++){
        scanf("%d %d %d %d %d",&x1,&y1,&x2,&y2,&g);
        door[x1][y1][x2][y2]=g; 
        door[x2][y2][x1][y1]=g;
    }
    scanf("%d",&s);
    for(int i=1;i<=s;i++){
        scanf("%d %d %d",&x1,&y1,&g);
        key[x1][y1]|=(1<<g);
    }
    printf("%d\n",spfa());
} 

状压BFS:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<bitset>
#define maxn 15
using namespace std;
struct node{
    int x;
    int y;
    int k;
    int t;
    node(){
        
    }
    node(int xx,int yy,int key,int tim){
        x=xx;
        y=yy;
        k=key;
        t=tim;
    }
    void debug(){
        printf("(%d,%d) tim=%d ",x,y,t);
        cout <<"key="<<bitset<10>(k)<<endl;
    }
};
int n,m,p,k,s; 
int vis[2005][maxn][maxn];
int key[maxn][maxn];
int door[maxn][maxn][maxn][maxn];
const int walkx[4]={1,-1,0,0};
const int walky[4]={0,0,1,-1};
int bfs(){
    queue<node>q;
    q.push(node(1,1,key[1][1],0));
    vis[key[1][1]][1][1]=1;
    while(!q.empty()){
        node now=q.front();
        q.pop();
//      now.debug();
        if(now.x==n&&now.y==m){
            return now.t;
        } 
        for(int i=0;i<4;i++){
            int x=now.x+walkx[i];
            int y=now.y+walky[i];
            if(x>=1&&x<=n&&y>=1&&y<=m){ 
                if(door[now.x][now.y][x][y]==0) continue;
                if((door[now.x][now.y][x][y]>=1 && (now.k & (1<<door[now.x][now.y][x][y])) !=0)||door[now.x][now.y][x][y]==-1){
                    if(vis[now.k|key[x][y]][x][y]) continue;
                    vis[now.k|key[x][y]][x][y]=1;
                    q.push(node(x,y,now.k|key[x][y],now.t+1)); 
                }
            } 
        }
    }
    return -1;
}

int main(){
    int x1,y1,x2,y2,g;
    scanf("%d %d %d",&n,&m,&p);
    scanf("%d",&k);
    memset(door,0xff,sizeof(door));
    for(int i=1;i<=k;i++){
        scanf("%d %d %d %d %d",&x1,&y1,&x2,&y2,&g);
        door[x1][y1][x2][y2]=g; 
        door[x2][y2][x1][y1]=g;
    }
    scanf("%d",&s);
    for(int i=1;i<=s;i++){
        scanf("%d %d %d",&x1,&y1,&g);
        key[x1][y1]|=(1<<g);
    }
    printf("%d\n",bfs());
} 

猜你喜欢

转载自www.cnblogs.com/birchtree/p/10602837.html