题目描述
在统计完朋友情况之后,小明又对大家的毕业学校产生兴趣,但是他觉得单纯的统计人数是一件非常无聊的事情,于是他设计了一个算法,同一所学校毕业的学生,第1个将获得1分,第2个获得2分,第3个获得4分…,第i个将获得2^i-1分,总分就是这所小学的得分,小明想知道得分最高的学校有多少分。
输入
输入文件score.in的第一行有两个整数n和m,n表示总人数,m表示已知的同校关系数量。
接下来n行,每行有2个以空格隔开的整数a和b,表示a和b是来自同一所学校,a和b均为1到n之间的整数。不会给出重复的信息。
输出
输出文件score.out只有一行,为所有学校中的最高得分。最后得分可能会很大,你只需要输出后100位即可,不足100位的请直接输出。
样例输入
5 3
1 2
3 4
1 3
样例输出
15
数据范围限制
60%的数据,1 <= n <= 10
80%的数据,1 <= n <= 70
100%的数据,1 <= n <= 10000,1 <= m <= 100000
提示
1、2、3、4来自同一所学校,该所学校所得的分数为1+2+4+8=15
TJ
这道题就是先打一个并查集,再算出结果即可。因为数据较大,所以要使用高精度。
BC
var
n,m,i,j,x,y,p,scorenumber,len:longint;
a,father,ans:array[0..20000]of longint;
function getfather(a:longint):longint;
begin
if father[a]=0 then exit(a);
getfather:=getfather(father[a]);
father[a]:=getfather;
end;
begin
assign(input,'score.in');reset(input);
assign(output,'score.out');rewrite(output);
readln(n,m);
for i:=1 to n do a[i]:=1;
for i:=1 to m do
begin
readln(x,y);
p:=getfather(x);
j:=getfather(y);
if p<>j then
begin
father[p]:=j;
a[j]:=a[j]+a[p];
if a[j]>scorenumber then scorenumber:=a[j];
end;
end;
len:=1;
ans[len]:=1;
for i:=1 to scorenumber do
begin
x:=0;
for j:=1 to len do
begin
ans[j]:=ans[j]*2+x;
x:=ans[j] div 10;
ans[j]:=ans[j] mod 10;
end;
if x>0 then
begin
inc(len);
ans[len]:=x;
end;
if len>100 then len:=100;
end;
ans[1]:=ans[1]-1;
i:=1;
while ans[i]<0 do
begin
inc(ans[i],10);
dec(ans[i+1]);
inc(i);
end;
for i:=len downto 1 do write(ans[i]);
writeln;
close(input);close(output)
end.