• Navigation Nightmare---poj1984(多关系并查集)


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

    给定n个城市,m条边告诉你城市间的相对距离,接下来q组询问,问你在第几条边添加后两城市的距离。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <stack>
    #include <map>
    #include <vector>
    using namespace std;
    typedef long long LL;
    #define PI 4*atan(1.0)
    #define N 42000
    #define met(a, b) memset(a, b, sizeof(a))
    
    int f[N], rx[N], ry[N], ans[N];
    ///rx[i]表示i和f[i]的x的偏移量,ry[i]是y的偏移量;
    struct node
    {
        int u, v, d, I, Id;
        char dir[10];
    }a[N], q[N];
    
    int cmp(node p, node q)
    {
        return p.Id<q.Id;
    }
    
    int Find(int x)
    {
        int k = f[x];
        if(x!=f[x])
        {
            f[x] = Find(f[x]);
            rx[x] += rx[k];
            ry[x] += ry[k];
        }
        return f[x];
    }
    
    void Union(int num)
    {
        int x = a[num].u, y = a[num].v;
        char ch = a[num].dir[0];
    
        int px = Find(x), py = Find(y);
    
        if(px != py)
        {
            f[px] = py;
    
            rx[px] = rx[y] - rx[x];
            ry[px] = ry[y] - ry[x];
    
            if(ch == 'E')
                rx[px] -= a[num].d ;
            if(ch == 'W')
                rx[px] += a[num].d;
            if(ch == 'N')
                ry[px] -= a[num].d;
            if(ch == 'S')
                ry[px] += a[num].d;
        }
    }
    int main()
    {
        int n, m, Q;
        while(scanf("%d %d", &n, &m)!=EOF)
        {
            met(a, 0);met(q, 0); met(ans, 0);
            for(int i=0; i<=n; i++)
                f[i] = i, rx[i] = ry[i] = 0;
    
            for(int i=1; i<=m; i++)
                scanf("%d %d %d %s", &a[i].u, &a[i].v, &a[i].d, a[i].dir);
    
            scanf("%d", &Q);
            for(int i=1; i<=Q; i++)
            {
                scanf("%d %d %d", &q[i].u, &q[i].v, &q[i].I);
                q[i].Id = i;
            }
    
            sort(q+1, q+Q+1, cmp);///不排序也可以;因为是按I的顺序给的;
            for(int pre=0, i=1; i<=Q; i++)
            {
                for(int j=pre+1; j<=q[i].I; j++)
                    Union(j);
    
                pre = q[i].I;
                int u = q[i].u, v = q[i].v;
    
                int px = Find(u);
                int py = Find(v);
    
                if(px != py) ans[q[i].Id] = -1;
                else ans[q[i].Id] = abs(rx[u]-rx[v]) + abs(ry[u]-ry[v]);
            }
            for(int i=1; i<=Q; i++)
                printf("%d
    ", ans[i]);
        }
        return 0;
    }
  • 相关阅读:
    CoCreateInstace 返回未知注册类别错误
    WINCE USB驱动组入
    CreateEvent ResetEvent SetEvent
    AppWidget的范例
    ubuntu下解决无声音的方法
    计算几何与图形学有关的几种常用算法
    Android实现GPS的打开与关闭
    深入剖析Android动画(Animation) (闪烁、左右摇摆、上下晃动等效果)
    中兴手机Linux下开发的方法
    移动网络环境下ReadBuffer的使用
  • 原文地址:https://www.cnblogs.com/zhengguiping--9876/p/5483254.html
Copyright © 2020-2023  润新知