B. 田田的公司 2014新生暑假个人排位赛04
时间限制 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
代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#define maxn 200000
//#define LOCAL
using namespace std;
int n,m,kind,x,y;
int father[maxn];
double a[maxn],sum[maxn];
int getfather(int x)
{
if(x==father[x])return x;
return father[x]=getfather(father[x]);
}
void Union(int x,int y)
{
int f1=getfather(x),f2=getfather(y);
if(f1!=f2)
{
father[f2]=f1;sum[f1]=sum[f1]+sum[f2];
}
}
int main()
{
#ifdef LOCAL
freopen("input.txt","r",stdin);
#endif // LOCAL
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);//cout<<n<<' '<<m<<endl;
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=n;i++){father[i]=i;sum[i]=a[i];}
for(int i=1;i<=m;i++)
{
scanf("%d",&kind);
if(kind==1){scanf("%d%d",&x,&y);Union(x,y);/*cout<<getfather(x)<<' '<<getfather(y)<<endl;cout<<sum[getfather(x)]<<' '<<sum[getfather(y)]<<endl;*/}
if(kind==2){scanf("%d",&x);printf("%lld\n",sum[getfather(x)]);}
}
//for(int i=1;i<=n;i++)printf("%lld ",sum[i]);
}
return 0;
}