zoukankan      html  css  js  c++  java
  • 小X的液体混合【并查集】

    题目大意:

    题目链接:http://10.156.17.250/JudgeOnline/showproblem?problem_id=2476 (学校内网)
    -在这里插入图片描述


    思路:

    我们把每种液体看成一个节点,会发生反应的种液体之间连边。那么就会出现一张不一定连通的图。
    例如:
    在这里插入图片描述
    我们现在随便找一个点,把它加入容器中。
    在这里插入图片描述
    那么可以肯定的是,与这个点连边的所有点加入到容器中都可以把危险系数乘22,那么就将这些点都放入容器中。
    在这里插入图片描述
    然后再重复刚刚的操作,我们可以发现,一个连通图中只有第一个放进去的是无法产生贡献的,而其他都是可以把危险系数乘2的。所以我们就只要判断有多少个连通图,这也就说明,有多少个点是不能产生贡献。那么剩余的nn-连通图个数的点都是可以让答案乘22的。
    那么就用并查集判断连通图个数,然后再高精乘即可。


    代码:

    #include <cstdio>
    #include <algorithm>
    #define N 1100
    #define MAXN 800
    using namespace std;
    
    int n,m,x,y,k,t,ans[MAXN+1],father[N];
    bool p[N];
    
    int find(int x)
    {
    	return x==father[x]?x:father[x]=find(father[x]);
    }
    
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for (int i=1;i<=n;i++)
    	 father[i]=i;
    	for (int i=1;i<=m;i++)
    	{
    		scanf("%d%d",&x,&y);
    		father[find(x)]=find(y);  //加入集合
    	}
    	for (int i=1;i<=n;i++)
    	 if (!p[find(i)])  //这个连通图还没有被计过
    	 {
    	 	p[find(i)]=1;
    	 	k++;  //连通图个数
    	 }
    	ans[MAXN]=1;
    	for (int j=1;j<=n-k;j++)
    	{
    		t=0;
    		for (int i=MAXN;i>=1;i--)
    		{
    			ans[i]=ans[i]*2+t;
    			t=ans[i]/10;
    			ans[i]%=10;
    		}
    	}
    	int i=1;
    	while (!ans[i]) i++;
    	for (;i<=MAXN;i++)
    	 printf("%d",ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    一个通用的事件监听函数全集
    单应性矩阵
    opencv姿态估计
    opencv相机标定
    Harris角点
    盒滤波Box Filter
    win10+vs2015+pcl1.8.1安装配置
    图像元素遍历
    阈值分割
    二叉树的层次遍历
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998474.html
Copyright © 2011-2022 走看看