zoukankan      html  css  js  c++  java
  • POJ 1984 Navigation Nightmare (并查集)

    题意:给定一组线段和方向,然后查询点的距离。

    思路:并查集的基本操作,在记录坐标偏移的时候注意一下,两个点之间和他们的根之间的坐标偏移关系可以用关系式表达出来,只要在纸上写一写就ok。查询输入的时候还是按ind排下序在处理线段。

    /*
    * 简单题 并查集的使用,就当是复习了。
    */
    #include
    <iostream>
    #include
    <cstdio>
    #include
    <algorithm>
    #include
    <memory.h>
    #include
    <cmath>
    #include
    <bitset>
    #include
    <queue>
    #include
    <vector>
    using namespace std;

    const int BORDER = (1<<20)-1;
    const int MAXSIZE = 37;
    const int MAXN = 40005;
    const int INF = 1000000000;
    #define CLR(x,y) memset(x,y,sizeof(x))
    #define ADD(x) x=((x+1)&BORDER)
    #define IN(x) scanf("%d",&x)
    #define OUT(x) printf("%d\n",x)
    #define MIN(m,v) (m)<(v)?(m):(v)
    #define MAX(m,v) (m)>(v)?(m):(v)
    #define ABS(x) ((x)>0?(x):-(x))

    typedef
    struct{
    int x,y;
    }Node;
    typedef
    struct{
    int a,b;
    int x,y;
    }Road;
    typedef
    struct{
    int a,b;
    int ind;
    }Ask;
    bool cmp(const Ask& a,const Ask& b)
    {
    return a.ind < b.ind;
    }

    Node node[MAXN];
    Road road[MAXN
    *1000];
    Ask qus[MAXN
    *10];
    int n,m,k;
    int pre[MAXN];

    int init()
    {
    for(int i = 0; i < MAXN; ++i)
    node[i].x
    = node[i].y = 0;
    CLR(pre,
    -1);
    return 0;
    }
    int find_set(int x)
    {
    int root = x;
    int c_px,c_py,p_py,p_px;
    int tmp = 0;
    p_px
    = node[x].x;
    p_py
    = node[x].y;
    while(pre[root] >= 0)
    {
    root
    = pre[root];
    node[x].x
    += node[root].x;
    node[x].y
    += node[root].y;
    }
    while( x != root)
    {
    tmp
    = pre[x];
    c_px
    = p_px;
    c_py
    = p_py;
    p_px
    = node[tmp].x;
    p_py
    = node[tmp].y;
    node[tmp].x
    = node[x].x - c_px;
    node[tmp].y
    = node[x].y - c_py;
    pre[x]
    = root;
    x
    = tmp;
    }
    return root;
    }
    void union_set(const int& root1,const int& root2,
    const int& x,const int& y)
    {
    pre[root2]
    += pre[root1];
    pre[root1]
    = root2;
    node[root1].x
    = x;
    node[root1].y
    = y;
    return ;
    }
    void print()
    {
    for(int i = 1; i <= n; ++i)
    printf(
    "(%d,%d) ",node[i].x,node[i].y);
    printf(
    "%\n");
    }
    int input()
    {
    int root1,root2,x,y,i,j,a,b,len;
    char c;
    for(i = 0; i < m; ++i)
    {
    scanf(
    "%d %d %d %c",&road[i].a,&road[i].b,&len,&c);
    x
    = y = 0;
    if(c=='N')
    y
    = len;
    else if(c=='S')
    y
    = -len;
    else if(c=='W')
    x
    = -len;
    else
    x
    = len;
    road[i].x
    = x;
    road[i].y
    = y;
    }
    IN(k);
    for(i = 0; i < k; ++i)
    scanf(
    "%d%d%d",&qus[i].a,&qus[i].b,&qus[i].ind);
    return 0;
    }
    int work()
    {
    int i,j,tmp,root1,root2,ans,a,b,t,x,y;
    int pre = 0;
    sort(qus,qus
    +k,cmp);
    for(i = 0; i < k; ++i)
    {
    a
    = qus[i].a;
    b
    = qus[i].b;
    t
    = qus[i].ind;
    for(; pre < t; ++pre)
    {
    root1
    = find_set(road[pre].a);
    root2
    = find_set(road[pre].b);
    if(root1 == root2)
    continue;
    x
    = road[pre].x - node[road[pre].a].x + node[road[pre].b].x;
    y
    = road[pre].y - node[road[pre].a].y + node[road[pre].b].y;
    union_set(root1,root2,x,y);
    }
    root1
    = find_set(a);
    root2
    = find_set(b);
    ans
    = -1;
    if(root1 != root2)
    OUT(ans);
    else
    {
    root1
    = ABS(node[a].x-node[b].x);
    root2
    = ABS(node[a].y-node[b].y);
    ans
    = root1 + root2;
    OUT(ans);
    }
    }
    return 0;
    }
    int main()
    {
    while(scanf("%d%d",&n,&m)!=EOF)
    {
    init();
    input();
    work();
    }
    return 0;
    }

  • 相关阅读:
    回顾2011,展望我的2012
    查看MS SQL SERVER数据库中表的大小
    MS SQL SERVER数字格式化显示,每三位加逗号
    MS SQL Server 保留一行,清除多余冗余数据
    ASP.NET Webform和ASP.NET MVC的区别
    Firefox的刷新功能与Safari,IE的差距
    TIOBE如何计算编程语言的排行?
    如何让ComboBox的下拉列表宽度自适应内容的宽度
    如何启用.NET中的Fusion Log
    JavaScript的clone函数的实现及应用条件
  • 原文地址:https://www.cnblogs.com/lvpengms/p/1717463.html
Copyright © 2011-2022 走看看