暑期个人赛--第四场--B

时间限制 3000 ms  内存限制 65536 KB

题目描述

田田家开了一家大公司,面对现在的形势,很多公司选择了联盟。联盟一旦成立就意味着联盟内的每个公司互相之间都认可结盟。所以当决定以一家公司为对手的时候就一定要计算出这家公司所在联盟的总实力值来决定有没有能力击败对手。
现在有n个公司,和m条信息。每条信息可能是某两个公司宣布联盟或者查询某个公司所在联盟的实力值

输入格式

多组数据
第一行为数据量T,每个case第一输入n,m ,之后一行输入n个数ai表示第i个公司的实力值,之后m行输入信息,有两种信息

第一种为两个公司联盟,该行为1 x y ,1表示联盟操作,即x,y两个公司联盟,

第二种为查询某个公司,该行为2 x,2表示查询操作,即查询x公司所在联盟的实力值;

T<=10
n,m<=10^5
ai<=10^6

输出格式

每个查询一行输出,输出那个公司联盟的实力值

输入样例

1
5 5
1 2 3 4 5
1 1 2
2 2
2 5
1 2 3
2 1

输出样例

3
5
6

赛中提交:WA 

赛后AC:YES

题目大意:

n家公司,每家有个实力值,任意两家公司可以联合,

联合之后这两家公司背后的其他公司也都相互联合,重新构成联盟。

要求完成两种操作,

一种是联合公司

一种是查询某公司的所在联盟实力值,也就是该联盟的所有公司的实力值之和



反省- -:

大坑~!!!!!!!!!!

好吧还是你自己太年轻太naive

因为每个公司的实力值的范围是ai<=10^6,而n的范围是n<=10^5

所以最后联盟实力值最大会超int,需要用long long

但是后来把数组改成longlong还是WA了

因为输出也要改成lld啊同学~!!!!



#include <iostream>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string>
#include <vector>
#include <list>
#include <map>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <numeric>
#include <functional>
#define maxn 100005

using namespace std;
long long par[maxn],rank[maxn],value[maxn];

void init(int n)
{
    for(int i=1;i<=n;i+=1){
        par[i]=i;
        rank[i]=0;
        value[i]=0;
    }
}

int find(int x)
{
    if(par[x]==x){
        return x;
    }
    else{
        return par[x]=find(par[x]);
    }
}

void unite(int x,int y)
{
    //int temptx=x,tempty=y;
    x=find(x);
    y=find(y);
    if(x==y){
        return;
    }

    if(rank[x]<rank[y]){
        par[x]=y;
        value[y]+=value[x];
    }
    else{
        par[y]=x;
        value[x]+=value[y];
        if(rank[x]==rank[y]){
            rank[x]+=1;
        }
    }
}


int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        int n,m;
        scanf("%d %d",&n,&m);
        init(n);
        for(int i=1;i<=n;i+=1){
            scanf("%d",&value[i]);
        }

        int q,com1=0,com2=0;
        for(int i=0;i<m;i+=1){
            scanf("%d",&q);
            if(q==1){
                scanf("%d %d",&com1,&com2);
                unite(com1,com2);
            }
            else{
                /*    scanf("%d",&com1);
                for(int i=1;i<=n;i+=1){
                    printf("%lld ",value[find(i)]);
                }
                printf("\n");*/
                scanf("%d",&com1);
                printf("%lld\n",value[find(com1)]);
            }
        }
    }

    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值