孤岛营救问题(最短路)

本题题目其实与网络流无关,一看题目发现是求从一个地方到另一个地方((1,1)到(n,m))的最快时间,很明显就是求最短路。

特别的是本题相邻的两个格子之间可能存在墙和或门,可能是死路也可能需要对应的钥匙开门,所以为啦解决对应的钥匙开门的问题,就可以来状态压缩,在dp[i][j][k]的第三维用二进制,既简单的位运算来表示在i行j列拥有钥匙状态为k时的最快速度。然后再bfs一遍(bfs的过程中可以写个判断函数,看能否开门或继续往下走,然后如果比此时的dp数组还小,则更新dp数组),最后for循环一遍找在dp数组在(n,m)时的最小值即可,最后记得特判一下-1。

      
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define M 15
#define INF 0x7fffffff/2

using namespace std;

int n,m,k,p,s;
int dp[M][M][1< q;

bool check(int x1,int y1,int x2,int y2,int key1)
{
    int tmp=door[x1][y1][x2][y2];
    if(tmp==-1)
        return true;
    else
    {
        if(tmp==0)
            return false;
        else
        {
            if(key1&(1<<(tmp-1)))
                return true;
            else
                return false;
        }
    }
}

void bfs()
{
    str1.x=1;
    str1.y=1;
    str1.key=0;
    str1.dis=0;
    q.push(str1);
    while(!q.empty())
    {
        str1=q.front();
        q.pop();
        for(int i=1;i<=4;i++)
        {
            str2.x=str1.x+fx[i];
            str2.y=str1.y+fy[i];
            if(str2.x>=1&&str2.x<=n&&str2.y>=1&&str2.y<=m&&check(str1.x,str1.y,str2.x,str2.y,str1.key))
            {
                str2.dis=str1.dis+1;
                str2.key=str1.key;
                str2.key |= fmap[str2.x][str2.y];
                if(str2.disdp[n][m][i])
            ans=dp[n][m][i];
    }
    if(ans==INF)
        printf("-1\n");
    else
        printf("%d\n",ans);

    return 0;
}

你可能感兴趣的:(网络流24题)