438. 田田的公司
时间限制 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;
}