avatar
fireworks99
keep hungry keep foolish

POJ 1984 Navigation Nightmare(valset)

Description

n个网格状的农田,每个农田之间有距离,会依次给出关系,在给出关系后询问两个农田之间的曼哈顿距离是多少?

写在前面

在两种情况下我会去看别人写的题解:
1.百wa不得其解
2.代码实现卡在某个点上
解决了这道题目后,自己写题解时要注意写明什么原因看了别人的题解
对于1,写清楚到底wa在哪个点上
对于2,写清楚别人怎么过的那个点

Analyze

对于此题,我对于”方向“无从下手,固然要记录当前结点到祖先节点的方向,开一个char数组标记吗?可路径压缩时又该如何更新彼此的数据?

解决办法:数字化

想想倘若是一维的,可以通过权值的正负区分左右,二维亦是如此。

以N、E为正,S、W为负

把祖先节点放在圆点上,更新每个点相对于祖先节点的NSEW。

那么同一祖先节点的节点间的哈密顿距离也就易求了。

Code

#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 40005;

int n, m, k;
char dir[10];
int u[N], v[N], w, ns[N], ew[N], val_ns[N], val_ew[N], pre[N];

int found(int x)
{
    if(pre[x] == -1)
        return x;

    int tem = found(pre[x]);
    ns[x] += ns[ pre[x] ];
    ew[x] += ew[ pre[x] ];
    return pre[x] = tem;
}

void unite(int a, int b, int v_ns, int v_ew)
{
    int aa = found(a);
    int bb = found(b);
    if(aa != bb)
    {
        pre[aa] = bb;
        ns[aa] = -ns[a] + v_ns + ns[b];
        ew[aa] = -ew[a] + v_ew + ew[b];
    }
}

int main()
{
    while(~scanf("%d %d", &n, &m))
    {
        memset(pre, -1, sizeof(pre));
        memset(ns ,  0,  sizeof(ns));
        memset(ew ,  0,  sizeof(ew));
        for(int i = 1; i <= m; ++i)
        {
            scanf("%d%d%d%s", &u[i], &v[i], &w, dir);
            if(dir[0] == 'N')
                val_ns[i] = w;
            else if(dir[0] == 'S')
                val_ns[i] = -w;
            else if(dir[0] == 'E')
                val_ew[i] = w;
            else
                val_ew[i] = -w;
        }

        scanf("%d", &k);
        int cnt = 0;
        for(int i = 0; i < k; ++i)
        {
            int a, b, idx;
            scanf("%d %d %d", &a, &b, &idx);
            while(cnt < idx)
            {
                cnt++;
                unite(u[cnt], v[cnt], val_ns[cnt], val_ew[cnt]);
            }
            if(found(a) != found(b))
                cout << "-1" << '\n';
            else
                cout << abs(ns[a] - ns[b]) + abs(ew[a] - ew[b]) << '\n';
        }
    }
    return 0;
}
Site by Baole Zhao | Powered by Hexo | theme PreciousJoy