poj 1984 Navigation Nightmare(带权并查集+小小的技巧)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj 1984 Navigation Nightmare(带权并查集+小小的技巧)相关的知识,希望对你有一定的参考价值。

题目链接:http://poj.org/problem?id=1984

题意:题目是说给你n个线,并告知其方向,然后对于后面有一些询问,每个询问有一个时间点,要求你输出在该时间点a,b的笛卡尔距离,如果不存在则输出-1

其实就是将权值分一下x,y,x表示x轴方向的权值,y表示y轴方向的权值。然后最后询问时稍微有点技巧

可以先记录一下每次询问的位置然后再按照时间点从小到大来排序最后这样就方便并查集了。

 

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;
const int M = 4e4 + 10;
int n , m , f[M] , ans[M];
struct TnT {
    int x , y , num , pos , sum;
    char aim;
}root[M] , T[M] , qu[M];
bool cmp(TnT a , TnT b) {
    return a.num < b.num;
}
int find(int x) {
    if(x == f[x])
        return x;
    int tmp = find(f[x]);
    root[x].x += root[f[x]].x;
    root[x].y += root[f[x]].y;
    return f[x] = tmp;
}
void Union(int x , int y , int addx , int addy) {
    int a = find(x) , b = find(y);
    if(a != b) {
        f[a] = b;
        root[a].x = root[y].x - root[x].x - addx;
        root[a].y = root[y].y - root[x].y - addy;
    }
}
int main() {
    int x , y , l , q;
    char cp[2];
    scanf("%d%d" , &n , &m);
    for(int i = 1 ; i <= m ; i++) {
        scanf("%d%d%d%s" , &x , &y , &l , cp);
        T[i].x = x , T[i].y = y , T[i].sum = l , T[i].aim = cp[0];
    }
    for(int i = 1 ; i <= n ; i++) {
        f[i] = i , root[i].x = 0 , root[i].y = 0;
    }
    scanf("%d" , &q);
    for(int i = 1 ; i <= q ; i++) {
        scanf("%d%d%d" , &qu[i].x , &qu[i].y , &qu[i].num);
        qu[i].pos = i;
    }
    sort(qu + 1 , qu + 1 + q , cmp);
    int temp = 1;
    for(int i = 1 ; i <= q ; i++) {
        for(int j = temp ; j <= qu[i].num ; j++) {
            x = T[j].x , y = T[j].y , l = T[j].sum;
            if(T[j].aim == ‘W‘)
                Union(x , y , -l , 0);
            if(T[j].aim == ‘E‘)
                Union(x , y , l , 0);
            if(T[j].aim == ‘N‘)
                Union(x , y , 0 , l);
            if(T[j].aim == ‘S‘)
                Union(x , y , 0 , -l);
        }
        temp = qu[i].num + 1;
        int a = find(qu[i].x) , b = find(qu[i].y);
        if(a != b)
            ans[qu[i].pos] = -1;
        else
            ans[qu[i].pos] = abs(root[qu[i].x].x - root[qu[i].y].x) + abs(root[qu[i].x].y - root[qu[i].y].y);
    }
    for(int i = 1 ; i <= q ; i++) {
        printf("%d\n" , ans[i]);
    }
    return 0;
}

以上是关于poj 1984 Navigation Nightmare(带权并查集+小小的技巧)的主要内容,如果未能解决你的问题,请参考以下文章

POJ 1984 Navigation Nightmare 经典带权并查集

poj1984 Navigation Nightmare

Navigation Nightmare POJ - 1984 (带权并查集)

POJ 1984Navigation Nightmare(带权并查集)

POJ_1984 Navigation Nightmare 并查集

POJ-1984-Navigation Nightmare+带权并查集(中级