Codeforces 445B DZY Loves Chemistry(并查集)

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\n",ans) ; 
41     return 0 ; 
42 }

 

posted @ 2017-07-04 10:41  third2333  阅读(156)  评论(0编辑  收藏  举报