zoukankan      html  css  js  c++  java
  • 2015 UESTC 数据结构专题H题 秋实大哥打游戏 带权并查集

    秋实大哥打游戏

    Time Limit: 1 Sec  Memory Limit: 256 MB

    题目连接

    http://acm.uestc.edu.cn/#/contest/show/59

    Description



    ”也许人生就是游戏,你却执意耕耘着春秋。” —— 秋实大哥叹道。

    秋实大哥是一个喜欢玩游戏的人,相较于其他种类的游戏,秋实大哥更喜欢自由开放的沙盒游戏,尤其是minecraft。

    现在,秋实大哥发现了N个独立的小岛(编号1,2,3.....N),于是他要把这些小岛连起来。

    每一次,秋实大哥会选择两个不同的小岛x(x是所在集合的中心)和y(y不一定是集合的中心),如果小岛x和小岛y不在一个集合里,就建立一条距离为|x−y| mod 1000的边,

    把这两片小岛合并为一个新的集合,中心为y原来所在的集合中心。

    但,秋实大哥想实时知道某一个小岛距当前所在集合中心的距离。由于秋实大哥忙着过节,所以他想请你帮忙。

    Input

    第一行有一个整数N表示小岛的个数。

    接下来有若干行,每一行为以下两种操作中的一种:

    I x y : 表示秋实大哥想要在x和y之间建立一条边。
    E x : 询问x到当前集合中心的距离。

    输入以一个大写字母O结束。

    1≤N≤100000,操作数≤200000。

    Output

    对于每一次询问,输出一个整数,即x到当前集合中心的距离,占一行。

    Sample Input

    3
    I 1 2
    E 1
    I 3 1
    E 3
    O

    Sample Output

    1
    3

    HINT


    题意


    题解:

    简简单单的带权并查集
    每次往上更新的时候,顺便把边权更新了就好
    记住得路径压缩

    代码:

    //qscqesze
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <set>
    #include <vector>
    #include <sstream>
    #include <queue>
    #include <typeinfo>
    #include <fstream>
    #include <map>
    typedef long long ll;
    using namespace std;
    //freopen("D.in","r",stdin);
    //freopen("D.out","w",stdout);
    #define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
    #define maxn 100010
    int mod=1000;
    #define eps 1e-9
    //const int inf=0x7fffffff;   //无限大
    const int inf=0x3f3f3f3f;
    /*
    inline ll read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int buf[10];
    inline void write(int i) {
      int p = 0;if(i == 0) p++;
      else while(i) {buf[p++] = i % 10;i /= 10;}
      for(int j = p-1; j >=0; j--) putchar('0' + buf[j]);
      printf("
    ");
    }
    */
    //**************************************************************************************
    int p[maxn];
    long long w[maxn];
    
    int fi(int x)
    {
        if(p[x]==x) return x;
        else
        {
            fi(p[x]);
            w[x]+=w[p[x]];
            p[x]=fi(p[x]);
        }
        return p[x];
    }
    bool un(int a,int b)
    {
        int x=fi(a);
        int y=fi(b);
        if(x==y) 
            return false;
        p[a]=y;
        w[a]=abs(a-b)%1000+w[b];
        return true;
    }
    int main()
    {
            int n,x,y;
            scanf("%d",&n);
            for(int i=0;i<=n;i++)
            {
                p[i]=i;
                w[i]=0;
            }
            char a[100];
            while(scanf("%s",&a)!=EOF)
            {
                if(a[0]=='O')
                    break;
                if(a[0]=='E')
                {
                    scanf("%d",&x);
                    fi(x);
                    printf("%lld
    ",w[x]);
                }
                else
                {
                    scanf("%d%d",&x,&y);
                    un(x,y);
                }
            }
        return 0;
    }
  • 相关阅读:
    Docker基本概念
    Docker 基本指令整理(一)
    其他软件技巧收藏
    Java ThreadPool的正确打开方式花钱的年华 | 江南白衣(5星推荐)
    java主线程等待所有子线程执行完毕在执行(常见面试题)
    (个人)Zookeeper集群环境部署
    linux下git怎么保存账号密码
    PHP跳出循环的方法及continue、break、exit的区别
    Linux 安装composer
    MySQL 删除数据库中重复数据方法
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4427292.html
Copyright © 2011-2022 走看看