zoukankan      html  css  js  c++  java
  • CodeForces 445B

    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).

    DZY喜欢化学,他喜欢混合化学物质。

    DZY有n种化学物质,其中有m对会发生反应。他想把这些化学物质倒进试管里,他需要按任何顺序一个一个地倒进去。

    让我们考虑一下试管的危险。空试管的危险是1。而每次DZY倒出一种化学品时,如果试管中已经有一种或多种化学品可以与之发生反应,那么试管的危险将乘以2。否则危险依然存在。

    把所有的化学药品按最佳顺序一个个倒出来,找出最大可能的危险。
    输入
    第一行包含两个空格分隔的整数n和m。
    下一个M线包含两个空间分离的整数席席(Yi)和Yi(1π,ω,x,y,y,y,ω,n)。这些整数意味着化学席I会与化学物质反应。每一对化学物质最多出现在输入中一次。
    把所有从1到n的化学物质按一定顺序排列。

    输出

    打印一个整数-最大可能的危险。
    实例
    输入
    10
    输出
    1
    输入
    2 1
    1 2
    输出
    2
    输入
    3 2
    1 2
    2 3
    输出
    4
    注意

    在第一个样本中,只有一种方法可以倒,而且危险不会增加。
    在第二个样本中,无论我们先倒第一种化学物质,还是先倒第二种化学物质,答案总是2。
    在第三个样本中,有四种方法可以达到最大可能的危险:2-1-3、2-3-1、1-2-3和3-2-1(即按浇注顺序排列的化学品数量)。

    题目大意:

    有n种化学物质,有m对会发生反应,危险程度默认是1,只要接下来加入的物质能与试管内任意一种物质发生反应,危险程度就*2,怎样的顺序往试管内添加1-n化学物质才能最大化危险程度,输出危险程度的最大值。

    解题思路:

    并查集,构建一个模型,假设有3棵树,a,b,c,则会发生a-1,b-1,c-1次反应,a+b+c==n,所以可以看出:发生反应的次数 = n-树的个数,可以这样去理解:

    • 并查集去连边,都连起来以后统计树的个数,结果为2n-树的个数
    • 还是并查集连边,我们还可以发现,最后发生反应的次数即是边的个数(前提是没有环),只要父节点不一样就连起来,反之则不连,每连一次cnt++。
      对连边的解释:为什么有环的不能要,假设有这样三对:1-2 2-3 3-1 ,这3个最多发生2次反应,但是连起来后会发生3次,显然这是不对的,所以有环的不必连边。

    AC代码:

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    typedef long long ll;
    using namespace std;
    const int N = 55;
    int f[N],n,m,cnt=0;
    int find(int x)
    {
    	return f[x]==x?x:f[x]=find(f[x]);
    }
    void merge(int x,int y)
    {
    	int t1=find(x);
    	int t2=find(y);
    	if(t1!=t2)//判环
    	{
    		cnt++;
    		f[t2]=t1;
    	}
    }
    int main()
    {
    	cin>>n>>m;
    	for(int i=1;i<=n;i++)
    	  f[i]=i;//父节点初始化为自己
    	for(int i=1;i<=m;i++)
    	{
    		int a,b;
    		cin>>a>>b;
    		merge(a,b);
    	}
    	ll ans=ll(1)<<cnt;//2^50 注意一下范围
    	cout<<ans<<endl;
    	//system("pause");
    	return 0;
    }
    
  • 相关阅读:
    《Linux内核分析》第七周学习笔记
    《深入理解计算机系统》第七章学习笔记
    《Linux内核设计与实现》第三章学习笔记
    《Linux内核分析》第六周学习笔记
    《Linux内核设计与实现》第十八章学习笔记
    《Linux内核分析》第五周学习笔记
    20182319彭淼迪 2018-2019-1《程序设计与数据结构》课程总结
    实验九报告
    第十周学习总结
    haffman树的实现
  • 原文地址:https://www.cnblogs.com/Hayasaka/p/14294253.html
Copyright © 2011-2022 走看看