zoukankan      html  css  js  c++  java
  • HDU 4829 Information(带权并查集)

    Information

    Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 422    Accepted Submission(s): 79


    Problem Description
    军情紧急,我们需要立刻开发出一个程序去处理前线侦察兵发回的情报,并做出相应的分析。现在由你负责其中的一个子模块,你需要根据情报计算出敌方坦克的位置。
    当敌方坦克静止时,侦察兵会尽力估算出它们之间的位置,而每当敌方坦克移动时,侦察兵都会记录下坦克新的位置并向你报告。每个坦克的位置可以由一个二维整数坐标来描述。
    前线发回的情报有四种格式:
    1 A B X Y
    表示A坦克移动到了与B坦克的相对位置是(X,Y)的地方,即XA = XB + X, YA=YB+Y。
    2 A X Y
    表示A坦克移动到了绝对位置是(X,Y)的地方,即XA = X, YA = Y。
    3 A B X Y
    表示发现了A坦克与B坦克的相对位置是(X,Y),即XA = XB + X, YA=YB+Y。
    4 A X Y
    表示发现了A坦克的绝对位置是(X,Y),即XA = X, YA = Y。
    我们需要你对于如下两种询问及时做出回应:
    5 A B
    表示询问A坦克与B坦克的相对位置是多少,即分别求出XA - XB 以及YA -YB
    6 A
    表示询问A坦克的绝对位置是多少,即求出XA 和YA
    其中A和B代表的是任意的一个坦克的编号,(X,Y)表示了坦克的二维坐标。你可以假设初始时刻我们对于敌方任何坦克的位置都一无所知,在此之后坦克的每一次移动都被侦察兵侦察到了。
    请注意两个坦克的坐标有可能相同。
     
    Input
    输入的第一行是一个整数T(T < 1000),表示共有T组数据。
    对于每组数据,第一行有一个整数N,表示这组数据有N次查询。接下来的每行表示一次查询,每次查询第一个数字代表是哪种询问,询问的格式详见上文。
    数据范围:
    0 < N <=100000, 0<A,B<=N 且 A<>B, X和Y都是整数且 0 <=X,Y<=10000 .
    测试数据中98%的数据N不超过50。
     
    Output
    对于每组数据,首先需要输出单独一行”Case #?:”,其中问号处应填入当前的数据组数,组数从1开始计算。
    对于每一个类型(1)或者(2)的询问,请把它们加入到你的记录中。
    对于每一个类型(3)或者(4)的询问,如果与之前记录的内容有矛盾,请输出”REJECT”并将这个情报忽略掉,如没有矛盾,请把它们加入到你的记录中。
    对于每一个类型(5)或者(6)的询问,如果根据之前的记录能推出结论,请输出两个整数X和Y,两个整数之间有一个空格;如果不能推出结论,请输出”UNKNOWN”。输出的所有信息都不包括引号。
     
    Sample Input
    2 7 1 1 2 3 4 2 3 4 5 3 4 5 2 1 4 6 2 2 3 2 4 6 2 5 4 1 6 3 6 6 3 4 3 2 2 6 3 2 4 2 3 5 3 4 3 3 4 1 2
     
    Sample Output
    Case #1: -9 -6 4 5 Case #2: UNKNOWN 2 2 0 -1 REJECT
     
    Source
     
    分析:求一些事物的相对关系,比较容易的会想到带权并查集。
               但这里有绝对位置,这个时候,我们可以看作它是与停在(0,0)的坦克的相对位置。
               然后在操作一和操作二的时候,会使坦克位置发生变化,发生位置变化的坦克可能已经存在于集合中,如果我们直接操作的话
               则会影响它所关联的其他坦克,所以我们创立一个新的节点来保存这种位置关系
    代码如下:
    #include<cstdio>
    #include <cmath>
    #include <queue>
    #include <stdlib.h>
    #include<iostream>
    #include<cstring>
    #include <vector>
    using namespace std;
    const int MAXN=2e5+100;
    int F[MAXN];
    int id[MAXN];
    int id_num;
    struct node
    {
        int x;
        int y;
    }val[MAXN];
    int Find(int a)
    {
        if(F[a]==-1||F[a]==a)return a;
        int tmp=Find(F[a]);
        val[a].x+=val[F[a]].x;
        val[a].y+=val[F[a]].y;
        return F[a]=tmp;
    }
    int newnode()
    {
       F[id_num]=-1;
       val[id_num].x=0;
       val[id_num].y=0;
       return id_num++;
    }
    int main()
    {
       int t,m,a,b,op,x,y,t1,t2,Case=0;
       scanf("%d",&t);
       while(t--)
       {
           memset(id,0,sizeof(id));
           Case++;
          id_num=0;
          printf("Case #%d:
    ",Case);
         scanf("%d",&m);
         for(int i=0;i<=m;i++)id[i]=newnode();
         while(m--)
         {
             scanf("%d",&op);
             b=0;
             if(op==1||op==2)
             {
                 if(op==1)scanf("%d%d%d%d",&a,&b,&x,&y);
                 else scanf("%d%d%d",&a,&x,&y);
                 id[a]=newnode();
                 t1=Find(id[a]);
                 t2=Find(id[b]);
                 F[t1]=t2;
                 val[t1].x=val[id[b]].x-val[id[a]].x+x;
                 val[t1].y=val[id[b]].y-val[id[a]].y+y;
             }
             else if(op==3||op==4)
             {
                if(op==3)scanf("%d%d%d%d",&a,&b,&x,&y);
                 else scanf("%d%d%d",&a,&x,&y);
                t1=Find(id[a]);
                t2=Find(id[b]);
                if(t1==t2)
                {
                   if(!(val[id[a]].x-val[id[b]].x==x&&val[id[a]].y-val[id[b]].y==y))
                   puts("REJECT");
                }
                else
                {
                 F[t1]=t2;
                 val[t1].x=val[id[b]].x-val[id[a]].x+x;
                 val[t1].y=val[id[b]].y-val[id[a]].y+y;
                }
             }
             else if(op==5||op==6)
             {
                 if(op==5)scanf("%d%d",&a,&b);
                 else scanf("%d",&a);
                 t1=Find(id[a]);
                 t2=Find(id[b]);
                 if(t1!=t2)
                 puts("UNKNOWN");
                 else
                 printf("%d %d
    ",val[id[a]].x-val[id[b]].x,val[id[a]].y-val[id[b]].y);
             }
         }
       }
        return 0;
    }
  • 相关阅读:
    【z02】选择客栈
    JavaEE(22)
    驱动表问题
    影响子查询展开的情况
    SQL*Net message from client
    等值链接和非等值链接
    ||拼接列关联和直接关联区别
    分页SQL优化
    SQL*Net more data to client
    SQL*Net message to client
  • 原文地址:https://www.cnblogs.com/a249189046/p/8177238.html
Copyright © 2011-2022 走看看