CF445B DZY Loves Chemistry 题解
Solution:
并查集裸题。
从 \(1\) 到 \(m\) 枚举,判断编号为 \(i\) 两种物质是否反应过(是否在一个并查集里),是则跳过,反之将这两个点所在的集合合并,并更新答案。
注意:
-
要初始化并查集。
-
\(\text{ans}\) 初值要设为 \(1\),以后的 \(\times 2\) 操作才会生效。
-
因为 \(1 \le n \le 50\),所以答案最大为 \(2^{49}\),需要开 \(\text{long long}\)。
Code:
#include<bits/stdc++.h> //万能头文件
#define int long long
using namespace std;
int f[1<<20];
void init(int x) //初始化函数
{
f[0]=0;
for(int i=1;i<=x;i++)
{
f[i]=i;//一开始,每个节点的爸爸都是它本身
}
}
int find(int x) //找爸爸函数
{
if(f[x]==x) return x;
return f[x]=find(f[x]);//路径压缩
}
void merge(int x,int y) //加点函数
{
int fx=find(x),fy=find(y);
if(fx==fy) return;
f[fx]=fy;
}
int n,m,ans=1;
struct R { int u,v,w; } a[1<<20];
signed main()
{
cin>>n>>m;
init(n);//初始化,有 n 个点的并查集
for(int i=1;i<=m;i++) cin>>a[i].u>>a[i].v;
for(int i=1;i<=m;i++)
{
int fx=find(a[i].u);
int fy=find(a[i].v);//找这两个点的爸爸
if(fx!=fy)
{
f[fx]=fy;// 合并集合
ans<<=1; //ans*=2,计算答案
}
}
cout<<ans;
return 0;
}
以下是博客签名,正文无关
本文来自博客园,作者:Wy_x,转载请在文首注明原文链接:https://www.cnblogs.com/Wy-x/articles/18704584
版权声明:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC-BY-NC-SA 4.0 协议)进行许可。

浙公网安备 33010602011771号