zoj3478

最短路

吐槽一下。。。最先开始写了个地图哈希,6kb,然后不是正解,又写了个spfa,4kb,还是不对,无奈抄标程,结果把spfa改成dijiestra就对了。。。

由于只有两个变量,所以我们设一个四维状态,d[x0][y0][x1][y1],然后就可以跑最短路了。如果是多维的话就得用哈希了。

但是那个终点的位置不固定,而且得做两次,因为控制的价钱不一样,所以两次取最小值。

#include<bits/stdc++.h>
using namespace std;
const int dx[] = {0, 0, -1, 1}, dy[] = {-1, 1, 0, 0};
struct position {
    int x0, y0, x1, y1;
    position(int x0 = 0, int y0 = 0, int x1 = 0, int y1 = 0) : x0(x0), y0(y0), x1(x1), y1(y1) {}
    bool friend operator < (position A, position B)
    {
        return A.x0 < B.x0;
    } 
};
int T, sx0, sy0, sx1, sy1;
queue<position> q;
set<position> inq;
int d[12][17][12][17];
char Map[12][17];
void spfa()
{
    memset(d, 0x3f3f, sizeof(d));
    q.push(position(sx0, sy0, sx1, sy1));
    d[sx0][sy0][sx1][sy1] = 0;
    while(!q.empty())
    {
        position x = q.front();
        q.pop();
        inq.erase(x);
//        if(x.x0 < 1 || x.x1 < 1 || x.y0 < 1 || x.y1 < 1 || x.x0 > 10 || x.x1 > 10 || x.y0 > 15 || x.y1 > 15 || (Map[x.x0][x.y0] == 'O' && Map[x.x1][x.y1] == 'O')) continue;
        if(Map[x.x0][x.y0] == 'O' && Map[x.x1][x.y1] == 'O') continue;
        for(int i = 0; i < 4; ++i)
        {
            position t = x;
            int cost = d[t.x0][t.y0][t.x1][t.y1];
            if(Map[t.x0][t.y0] != 'O')
            {
                t.x0 += dx[i];
                t.y0 += dy[i];
                cost += 2;
                if(Map[t.x0][t.y0] == 'X')
                {
                    t.x0 = x.x0;
                    t.y0 = x.y0;
                }
            }
            if(Map[t.x1][t.y1] != 'O')
            {
                t.x1 += dx[i];
                t.y1 -= dy[i];
                cost += 3;
                if(Map[t.x1][t.y1] == 'X')
                {
                    t.x1 = x.x1;
                    t.y1 = x.y1;
                }
            }
            if(d[t.x0][t.y0][t.x1][t.y1] > cost)
            {
                d[t.x0][t.y0][t.x1][t.y1] = cost;
                if(inq.find(position(t.x0, t.y0, t.x1, t.y1)) == inq.end())
                {
                    inq.insert(position(t.x0, t.y0, t.x1, t.y1));
                    q.push(position(t.x0, t.y0, t.x1, t.y1));
                }
            }
        }
        position t = x;
        int cost = d[t.x0][t.y0][t.x1][t.y1];
        if(abs(x.x0 - x.x1) + abs(x.y0 - x.y1) == 1 && ((Map[x.x0][x.y0] == 'O') ^ (Map[x.x1][x.y1] == 'O'))) 
        {
            if(Map[x.x0][x.y0] == 'O')
            {
                t.x0 = x.x1;
                t.y0 = x.y1;
            }
            else
            {
                t.x1 = x.x0;
                t.y1 = x.y0;
            }
            cost += 11;
        }            
        if(d[t.x0][t.y0][t.x1][t.y1] > cost)
        {
            d[t.x0][t.y0][t.x1][t.y1] = cost;
            if(inq.find(position(t.x0, t.y0, t.x1, t.y1)) == inq.end())
            {
                inq.insert(position(t.x0, t.y0, t.x1, t.y1));
                q.push(position(t.x0, t.y0, t.x1, t.y1));
            }
        } 
    }
    printf("%d\n", d[1][8][1][8] == 1061109567 ? -1 : d[1][8][1][8]);
}
int main()
{
    scanf("%d", &T);
    while(T--)
    {
        inq.clear();
        for(int i = 0; i <= 12; ++i)
            for(int j = 0; j <= 17; ++j) 
                Map[i][j] = 'X';
        for(int i = 1; i <= 10; ++i)
        {
            char s[17];
            scanf("%s", s + 1);
            for(int j = 1; j <= 15; ++j) 
            {
                if(s[j] == 'H') s[j] = '.';
                Map[i][j] = s[j];
            }
        }
        scanf("%d%d%d%d", &sx0, &sy0, &sx1, &sy1);
        spfa();
    }
    return 0;
}
View Code

 

posted @ 2017-07-09 10:28  19992147  阅读(150)  评论(0编辑  收藏  举报