B. DZY Loves Chemistry

time limit per test:1 second
memory limit per test:256 megabytes
input:standard input
output:standard output

DZY loves chemistry, and he enjoys mixing chemicals.

DZY has n chemicals, and m pairs of them will react. He wants to pour these chemicals into a test tube, and he needs to pour them in one by one, in any order.

Let's consider the danger of a test tube. Danger of an empty test tube is 1. And every time when DZY pours a chemical, if there are already one or more chemicals in the test tube that can react with it, the danger of the test tube will be multiplied by 2. Otherwise the danger remains as it is.

Find the maximum possible danger after pouring all the chemicals one by one in optimal order.

Input

The first line contains two space-separated integers n and m .

Each of the next m lines contains two space-separated integers xi and yi (1 ≤ xi < yi ≤ n). These integers mean that the chemical xi will react with the chemical yi. Each pair of chemicals will appear at most once in the input.

Consider all the chemicals numbered from 1 to n in some order.

Output

Print a single integer — the maximum possible danger.

Examples

input

1 0

output

1

input

2 1
1 2

output

2

input

3 2
1 2
2 3

output

4

Note

In the first sample, there's only one way to pour, and the danger won't increase.

In the second sample, no matter we pour the 1st chemical first, or pour the 2nd chemical first, the answer is always 2.

In the third sample, there are four ways to achieve the maximum possible danger: 2-1-3, 2-3-1, 1-2-3 and 3-2-1 (that is the numbers of the chemicals in order of pouring).

能够相互反应的元素构成一个集合,用并查集找到有几个集合,从每个集合中各取一个放入杯中,然后不管从哪个集合取一个元素加入杯中都能够有办法翻倍,所以答案就是2的(元素个数减去集合个数)次方。

 //2017-08-06
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; const int N = ;
int fa[N], arr[N];
long long pow[N]; void init(){
pow[] = ;
for(int i = ; i < N; i++){
fa[i] = i;
pow[i] = pow[i-]*;
}
} int getfa(int x){
if(fa[x] == x)return x;
return fa[x] = getfa(fa[x]);
} void Merge(int a, int b){
int af = getfa(a);
int bf = getfa(b);
if(af != bf){
fa[bf] = af;
}
} int main()
{
int n, m, a, b;
while(scanf("%d%d", &n, &m)!=EOF){
init();
while(m--){
scanf("%d%d", &a, &b);
Merge(a, b);
}
int cnt = ;
for(int i = ; i <= n; i++)
if(fa[i] == i)cnt++;
if(m == )printf("1\n");
else printf("%lld\n", pow[n-cnt]);
} return ;
}
 import java.util.*;

 public class Main{
static final int N = 60;
static int[] fa = new int[N];
static int[] arr = new int[N];
static long[] pow = new long[N]; static void init(){
pow[0] = 1;
for(int i = 1; i < N; i++){
fa[i] = i;
pow[i] = pow[i-1]*2;
}
} static int getfa(int x){
if(fa[x] == x)return x;
return fa[x] = getfa(fa[x]);
} static void merge(int a, int b){
int af = getfa(a);
int bf = getfa(b);
if(af != bf)
fa[bf] = af;
} public static void main(String args[]){
int n, m, a, b;
Scanner cin = new Scanner(System.in);
while(cin.hasNext()){
n = cin.nextInt();
m = cin.nextInt();
init();
for(int i = 0; i < m; i++){
a = cin.nextInt();
b = cin.nextInt();
merge(a, b);
}
int cnt = 0;
for(int i = 1; i <= n; i++)
if(fa[i] == i)
cnt++;
if(m == 0)System.out.printf("1\n");
else System.out.println(pow[n-cnt]);
}
}
}

Codeforces445B(SummerTrainingDay06-N 并查集)的更多相关文章

  1. BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]

    4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...

  2. 关押罪犯 and 食物链(并查集)

    题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值"( ...

  3. 图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用

    图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 ...

  4. bzoj1854--并查集

    这题有一种神奇的并查集做法. 将每种属性作为一个点,每种装备作为一条边,则可以得到如下结论: 1.如果一个有n个点的连通块有n-1条边,则我们可以满足这个连通块的n-1个点. 2.如果一个有n个点的连 ...

  5. [bzoj3673][可持久化并查集 by zky] (rope(可持久化数组)+并查集=可持久化并查集)

    Description n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0& ...

  6. [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)

    Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...

  7. 【BZOJ-3673&3674】可持久化并查集 可持久化线段树 + 并查集

    3673: 可持久化并查集 by zky Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 1878  Solved: 846[Submit][Status ...

  8. Codeforces 731C Socks 并查集

    题目:http://codeforces.com/contest/731/problem/C 思路:并查集处理出哪几堆袜子是同一颜色的,对于每堆袜子求出出现最多颜色的次数,用这堆袜子的数目减去该值即为 ...

  9. “玲珑杯”ACM比赛 Round #7 B -- Capture(并查集+优先队列)

    题意:初始时有个首都1,有n个操作 +V表示有一个新的城市连接到了V号城市 -V表示V号城市断开了连接,同时V的子城市也会断开连接 每次输出在每次操作后到首都1距离最远的城市编号,多个距离相同输出编号 ...

随机推荐

  1. Zookeeper客户端Curator使用详解

    Zookeeper客户端Curator使用详解 前提 最近刚好用到了zookeeper,做了一个基于SpringBoot.Curator.Bootstrap写了一个可视化的Web应用: zookeep ...

  2. JVM锁优化

    1. 概述 JDK1.6版本花费了大量精力去实现各种锁优化,如适应性自旋,锁消除,锁粗化,轻量级锁,偏向锁等,这些技术都是为了在线程期间更高效的共享数据,以及解决竞争问题. 2. 自旋锁与自适应自旋 ...

  3. WCF:wsdl

  4. postgresql-脏页和缓存失效

    脏页和缓存失效 https://www.cnblogs.com/flying-tiger/p/7885478.html Dirty pages and cache invalidation 我们一直在 ...

  5. python并发编程之进程池,线程池concurrent.futures

    进程池与线程池 在刚开始学多进程或多线程时,我们迫不及待地基于多进程或多线程实现并发的套接字通信,然而这种实现方式的致命缺陷是:服务的开启的进程数或线程数都会随着并发的客户端数目地增多而增多, 这会对 ...

  6. linux安装mysql数据库和简单配置

  7. POJ 2860

    #include<iostream> #define MAXN 20 using namespace std; int a_1[MAXN]; int a_2[MAXN]; int main ...

  8. 传染病传播模型(SIS)Matlab代码

    function spreadingability=sir(A,beta,mu) for i=1:length(A) for N=1:50%随机次数 InitialState=zeros(length ...

  9. 解决ubuntu安装系统默认没有创建root用户

    安装ubuntu操作系统的时候,默认没有设置root账户的步骤!!! 这样在操作系统安装完成之后,就没有root用户, 一般,当前的普通用户,如果需要执行一些命令的时候,只要在命令前边加上sudo就行 ...

  10. (转)Python自动化运维之13、异常处理及反射(__import__,getattr,hasattr,setattr)

    原文:http://www.cnblogs.com/xiaozhiqi/p/5778856.html https://blog.csdn.net/zong596568821xp/article/det ...