zoukankan      html  css  js  c++  java
  • 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
    " , ans[i]);
        }
        return 0;
    }
    
  • 相关阅读:
    Vue的使用
    Bootstrap 提示工具(Tooltip)插件
    基于layerpage 前后端异步分页
    bootstrap的selectpicker的方法
    移动端好用的下拉加载上拉刷新插件 dropload插件
    vue的安装
    chromium ②
    chromium ①
    一些技术博客 集合
    提高pv uv
  • 原文地址:https://www.cnblogs.com/TnT2333333/p/6601732.html
Copyright © 2011-2022 走看看