思路
并查集,可联通的点位于同一个并查集,它们拥有共同的祖父节点,或父节点。
#include<cstdio>
int ans[501],f[1001],n,m,t;
int find(int d){ //寻找父节点
int s=d;
while(f[s]!=s) s=f[s]; //路径压缩
return s;
}
void c(){ //高精乘
int j=0;
for(int i=1;i<=500;++i){
ans[i]=ans[i]*2+j;
j=ans[i]/100;
ans[i]=ans[i]%100;
}
}
void scan(){ //输入
int x,y;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i) f[i]=i;
for(int i=1;i<=m;++i){
scanf("%d%d",&x,&y);
x=find(x); //让x的父亲的父亲=y的父亲
f[x]=find(y);
}
}
void print(){ //高精输出
int i=500;
while(ans[i]==0) --i;
printf("%d",ans[i]);
--i;
for(i;i;--i){
if(ans[i]<10) printf("0");
printf("%d",ans[i]);
}
}
void work(){
scan();
for(int i=1;i<=n;++i) //统计多少个并查集
if(f[i]==i) t++;
ans[1]=1;
for(int i=1;i<=n-t;++i) //去掉不能产生反应的
c();
print();
}
int main(){
work();
}