Codeforces 445B DZY Loves Chemistry(并查集)
题目大意:有若干种化学药品,给出两两会反应的关系,
现在要将药物依次放入一个容器中,容器中的化学药品可以互相反应,如果当前放入的药品能与已经在容器中的某一药品反应,
那么危险值翻倍,即*2,初始值为1,求一顺序,使得为危险值最大。
解题思路:并查集求最小联通分量s,2^(n-|s|)即为答案。
这道题 就是并查集 求出 连完边以后总共有几个连通块 |S|
然后答案就是 2^(n-|s|)
关于并查集 并查集 是用来维护不相交集合的数据结构,虽然我也不知道什么意思
并查集有一个优点 动态 加边 非常 快 然后 也可以 O(1) 查询 两个点的连通性
支持动态加边 据说也能够 动态删边 但是我不会 QwQ
1 #include <bits/stdc++.h> 2 #define ll long long 3 using namespace std ; 4 5 const int maxn = 51 ; 6 int n,m,sum ; 7 int f[maxn] ; 8 ll ans ; 9 10 inline int getfather(int x) 11 { 12 if(f[x]==x) return x ; 13 return f[ x ] = getfather(f[ x ]) ; 14 } 15 16 inline void Union(int x,int y) 17 { 18 int xx = getfather(x) ; 19 int yy = getfather(y) ; 20 if(xx!=yy) f[ xx ] = yy ; 21 } 22 23 int main() 24 { 25 scanf("%d%d",&n,&m) ; 26 for(int i=1;i<=n;i++) f[ i ] = i ; 27 int x,y ; 28 for(int i=1;i<=m;i++) 29 scanf("%d%d",&x,&y) , Union(x,y) ; 30 31 for(int i=1;i<=n;i++) f[ i ] = getfather(f[ i ]) ; 32 33 sort(f+1,f+n+1) ; 34 f[ 0 ] = -100 ; 35 36 for(int i=1;i<=n;i++) 37 if(f[ i ]!=f[i-1]) sum++ ; 38 ans = 1 ; 39 for(int i=1;i<=n-sum;i++) ans = ans*2 ; 40 printf("%lld ",ans) ; 41 return 0 ; 42 }