zoukankan      html  css  js  c++  java
  • 计蒜客练习题:接龙(带权并查集)

    蒜头君在玩一种接龙的游戏,蒜头君有 30000张卡片分别放在 30000列,每列依次编号为 1,2,...,30000。 同时,蒜头君也把每张卡片依次编号1,2,...,30000。

    游戏开始,蒜头君让让第i张卡片处于第i(i=1,2,...,30000)列。

    然后蒜头君会发出多次指令,每次调动指令M i j会将第i张卡片所在的队列的所有卡片, 作为一个整体(头在前尾在后)接至第j张卡片所在的队列的尾部。

    蒜头君还会查看当前的情况,发出C i j的指令,即询问电脑,第i张卡片与第 j张卡片当前是否在同一个队列中, 如果在同一列中,那么它们之间一共有多少张卡片。

    聪明的你能不能编写程序处理蒜头君的指令,以及回答蒜头君的询问呢? 输入格式 第一行有一个整数T(1≤T≤500000),表示总共有T条指令。以下有T行,每行有一条指令。

    指令有两种格式: M i j: i和j是两个整数(1≤i,j≤30000),表示指令涉及的卡片编号。

    你需要让第i张卡片所在的队列的所有卡片,作为一个整体(头在前尾在后)接至第j 张卡片所在的队列的尾部, 输入保证第i号卡片与第 j 号卡片不在同一列。

    C i j:i和j是两个整数(1≤i,j≤30000),表示指令涉及的卡片编号。该指令是蒜头君的询问指令。

    输出格式:如果是蒜头君调动指令,则表示卡片排列发生了变化,你的程序要注意到这一点,但是不要输出任何信息;

    如果是蒜头君的询问指令,你的程序要输出一行,仅包含一个整数,表示在同一列上, 第i号卡片与第j号卡片之间的卡片数目(不包括第i张卡片和第j 张卡片)。

    如果第i号卡片与第j号卡片当前不在同一个队列种中,则输出−1。

    样例输入:

    4
    M 2 3
    C 1 2
    M 2 4
    C 4 2

    样例输出:

    -1
    1


    AC代码(参考网上):
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    
    const int MAXN = 30000 + 5;
    
    int father[MAXN], dis[MAXN], Size[MAXN];
    int n, k, ans;
    
    int Find(int x)
    {
        if (x == father[x]) return x;
        int temp = father[x];
        father[x] = Find(father[x]);
        dis[x] = (dis[x] + dis[temp]);
        return father[x];
    }
    
    void Union(int x, int y)
    {
        int fx = Find(x), fy = Find(y);
        if (fx != fy)
        {
            father[fx] = fy;
            dis[fx] = Size[fy];
            Size[fy] += Size[fx];
        }
    }
    
    int check(int x, int y)
    {
        int ans = -1;
        if (Find(x) == Find(y))
            ans = abs(dis[x] - dis[y]) - 1;
        return ans;
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin >> n;
        for(int i = 1; i <= n; i++)
            father[i] = i, dis[i] = 0, Size[i] = 1;
        ans = 0;
        while (n--)
        {
            string a; 
            int b, c;
            cin >> a >> b >> c;
            if (a == "C") cout << check(b, c) << endl;
            else Union(b, c);
        }
        return 0;
    }
    View Code
    感觉看看代码也是懂为什么这样写的,但是当自己写的时候还是要参考网上的题解。(这可能是因为我太菜了吧
    网上的人都说这是一道带权并查集的模板题,很easy(然而菜鸡并不这么想
    仔细想想主要是dis的合并那一块写不出来,之后没想到要开一个size数组来记录整个集合的元素(天真的我只想开一个dis完事儿
    唉,还是在明天再写写看看是不是真的懂了吧。


  • 相关阅读:
    Representation Data in OpenCascade BRep
    Render OpenCascade Geometry Surfaces in OpenSceneGraph
    Render OpenCascade Geometry Curves in OpenSceneGraph
    OpenCascade Shape Representation in OpenSceneGraph
    Geometry Surface of OpenCascade BRep
    Geometry Curve of OpenCascade BRep
    Tyvj2017清北冬令营入学测试
    Spfa算法模板
    洛谷1016 旅行家的预算
    洛谷1290 欧几里得的游戏
  • 原文地址:https://www.cnblogs.com/Vikyanite/p/11832420.html
Copyright © 2011-2022 走看看