zoukankan      html  css  js  c++  java
  • (补题 Uva 3027)Corporative Network

    原题链接(戳我~)

    题目大意&解题思路

    有n个节点,然后执行I_u_v(把u的父节点设为v)和E_u(询问u到根节点的距离)。

    利用带权并查集

    Sample Input

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

    Sample output

    0
    2
    3
    5
    

    代码样例

    利用pair存放父节点(first)以及权值(second)

    计算距离

    rela[a].second = ((int)(fabs(a - b))) % 1000;
    

    查找根节点(find_root)

    这里住一定不要先压缩再将权值相加(会漏掉某些节点的权值)

     int find_root(int x){
     if (x == rela[x].first)
            return x;
        int x_root = find_root(rela[x].first);
        rela[x].second += rela[rela[x].first].second;
        return rela[x].first = x_root;
        }
    

    完整代码

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <set>
    #include <string>
    #include <map>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <cmath>
    using namespace std;
    // typedef long long LL;
    
    const int maxn = 200010;
    
    pair<int, int> rela[maxn]; //first is father root second is value;
                               //value means the distinct between root & point;
    
    void init()
    {
        for (int i = 0; i < maxn; i++)
        {
            rela[i].first = i;
            rela[i].second = 0;
        }
    }
    
    int find_root(int x)
    {
        if (x == rela[x].first)
            return x;
        int x_root = find_root(rela[x].first);
        rela[x].second += rela[rela[x].first].second;
        return rela[x].first = x_root;
    }
    
    void union_vertices(int a, int b)
    {
        rela[a].first = b;
        rela[a].second = ((int)(fabs(a - b))) % 1000;
    }
    
    int main()
    {
        int t;
        cin >> t;
        while (t--)
        {
            init();
            int n;
            cin >> n;
            char cmd[10];
            while (~scanf("%s", cmd))
            {
                if (cmd[0] == 'O')
                    break;
                else if (cmd[0] == 'I')
                {
                    int a, b;
                    scanf("%d%d", &a, &b);
                    union_vertices(a, b);
                }
                else
                {
                    int a;
                    scanf("%d", &a);
                    find_root(a);
                    cout << rela[a].second << endl;
                }
            }
        }
        // system("pause");
        return 0;
    }
    
  • 相关阅读:
    WAP协议研究笔记—彩信的传输
    应用程序重起自身等几则技巧
    谁妨碍了我们快乐
    国庆长假总结
    关于输入法的两个问题
    反刍
    为什么,一个思维方式的问题,一个习惯的问题,已经意识到了这一点,
    电影池子,
    幻想下,
    意识流,
  • 原文地址:https://www.cnblogs.com/cafu-chino/p/11759509.html
Copyright © 2011-2022 走看看