• Hrbust 2240 土豪的时代


    题意:中文题……不总结了……(好懒0-0)

    土豪圈有一个习惯:从来不告诉别人自己到底有多少钱。但他们总是喜欢和其他土豪比较,来看看谁更土豪。于是每每几天,就会爆出一些关于土豪资产的消息,比如A土豪比B土豪多了3254万,C土豪比D土豪少2124万等等,从这些消息中也很容易推测出某两个土豪之间的资产关系。小破觉得和土豪交朋友是件非常愉快的事,但她想知道,某两个土豪,哪个更土豪。你能帮帮她么。

    解法:并查集+向量偏移。

    做这个题之前没接触过向量偏移……经典的食物链也没做过……看了这篇博客http://hi.baidu.com/tomspirit/item/d1f2a19b2aaf36d27a7f0158

    对于本题来说,每个点到父亲节点的偏移量即为根节点比自己多了多少钱,则当查询a和b时,如果a和b在同一集中,delta[b] - delta[a]即为所求。

    当新加入两个土豪的关系a比b多v时,c为a的父亲,d为b的父亲,向量表示如下:

    已知c -> a, a -> b, d -> b,则c -> d = c -> a + v - d -> b, 即father[d] = c; delta[d] = delta[a] + v - delta[b];,d的根节点更新为c。

    代码:

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<string.h>
    #include<math.h>
    #include<limits.h>
    #include<time.h>
    #include<stdlib.h>
    #include<map>
    #include<queue>
    #include<set>
    #include<stack>
    #include<vector>
    #define LL long long
    using namespace std;
    int father[100005];
    int delta[100005];
    int FIND(int a)
    {
        if(father[a] != a)
        {
            int temp = FIND(father[a]);
            delta[a] += delta[father[a]];
            father[a] = temp;
        }
        return father[a];
    }
    int main()
    {
        int n;
        while(~scanf("%d", &n))
        {
            for(int i = 0; i <= n; i++)
                father[i] = i;
            memset(delta, 0, sizeof(delta));
            for(int i = 0; i < n; i++)
            {
                int cmd;
                scanf("%d", &cmd);
                if(cmd == 1)
                {
                    int a, b, v;
                    scanf("%d%d%d", &a, &b, &v);
                    int c = FIND(a), d = FIND(b);
                    if(c != d)
                    {
                        father[d] = c;
                        delta[d] = delta[a] + v - delta[b];
                    }
                }
                else
                {
                    int a, b;
                    scanf("%d%d", &a, &b);
                    int c = FIND(a);
                    int d = FIND(b);
                    if(c != d)
                        puts("?");
                    else
                    {
                        printf("%d
    ", delta[b] - delta[a]);
                    }
                }
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    面试官本拿求素数搞我,但被我用素数筛优雅的“回击“了
    手写玩具
    【LeetCode】5638.吃苹果的最大数目
    【LeetCode】290.单词规律(双映射)
    【LeetCode】42.接雨水
    【LeetCode】84.柱状图中最大的矩形
    【LeetCode】135.分发糖果
    【Leetcode】746.使用最小花费爬楼梯
    【LeetCode】316.去除重复字母
    【LeetCode】三题解决常见异或运算题
  • 原文地址:https://www.cnblogs.com/Apro/p/4399322.html
Copyright © 2020-2023  润新知