zoukankan      html  css  js  c++  java
  • hdu1272

    hdu1272

    小希的迷宫

    0x00 Tags

    并查集

    0x01 题目简介

    1. 并查集产生的每一个集合都是一棵树
    2. 流程:初始化;查找–判断两个元素是否在一个集合;合并
    3. 查找过程递归可能会爆栈,采用递归方式进行路径压缩
    4. 用并查集判断是否有环;对同一个集合来说只存在一个根节点
    5. 合并的过程是一个建树的过程,当合并失效时,说明两个节点在同一个集合中,这两点连的边成环
    6. 使用isroot数组记录有几个根节点–有几个不同的集合

    判断是否连通:顶点数==边数+1

    0x02 代码

    代码—与上面思想相同

    #include<bits/stdc++.h>
    
    using namespace std;
    
    
    const int maxn = 100010;
    
    int root[maxn];
    
    // 成环标志
    bool circle;
    
    void Init()
    {
    	for (int i = 1; i < maxn; i++)
    	{
    		root[i] = i;
    	}
    }
    
    int Find(int x)
    {
    	//return x == root[x] ? x : Find(root[x]);
    
    	while (x != root[x])
    	{
    		x = root[x];
    	}
    
    	return x;
    }
    
    
    void Union(int x, int y)
    {
    	x = Find(x);
    	y = Find(y);
    
    	if (x != y) root[x] = y;
    	else circle = 0;  // 成环
    }
    
    
    
    int main()
    {
    	set<int> v;  // 记录顶点
    
    	int a, b, sum;  // sum记录边数
    
    	while (scanf("%d%d",&a,&b) != EOF)
    	{
    		if (a == -1 && b == -1) break;
    
    		if (a == 0 && b == 0)
    		{
    			printf("Yes
    ");
    			continue;
    		}
    
    		Init();
    
    		sum = 1;
    		circle = false;
    		v.insert(a);
    		v.insert(b);
    
    		if (!circle)
    			Union(a, b);
    
    		while (1)
    		{
    			scanf("%d%d", &a, &b);
    
    			if (a == 0 && b == 0) break;
    
    			v.insert(a);
    			v.insert(b);
    
    			if (!circle) Union(a, b);
    
    			sum++;
    		}
    
    		/*
    		while (scanf("%d%d", &a, &b) != EOF)
    		{
    			if (a == 0 && b == 0) break;
    			v.insert(a);
    			v.insert(b);
    			
    			if (!circle) Union(a, b);
    			sum++;
    		}
    
    		*/
    
    		if (!circle && v.size() == sum + 1)
    			printf("Yes
    ");
    		else
    			printf("No
    ");
    
    		v.clear();
    	}
    
    	return 0;
    }
    

    代码二

    #include<bits/stdc++.h>
    
    using namespace std;
    
    
    const int maxn = 100010;
    
    int root[maxn], sign[maxn];
    
    // 成环标志
    int flag;
    
    void Init()
    {
    	for (int i = 1; i < maxn; i++)
    	{
    		root[i] = i;
    		sign[i] = 0;
    	}
    }
    
    int Find(int x)
    {
    	//return x == root[x] ? x : Find(root[x]);
    
    	while (x != root[x])
    	{
    		x = root[x];
    	}
    
    	return x;
    }
    
    
    void Union(int x, int y)
    {
    	x = Find(x);
    	y = Find(y);
    
    	if (x != y) root[x] = y;
    	else flag = 0;
    }
    
    
    
    int main()
    {
    
    	int a, b;
    
    	while (scanf("%d%d",&a,&b) != EOF)
    	{
    		if (a == -1 && b == -1) break;
    
    		if (a == 0 && b == 0)
    		{
    			printf("Yes
    ");
    			continue;
    		}
    
    		Init();
    
    		sign[a] = sign[b] = 1;
    
    		flag = 1;
    
    		Union(a, b);
    
    		while (scanf("%d%d", &a, &b) != EOF)
    		{
    			if (a == 0 && b == 0) break;
    			Union(a, b);
    			sign[a] = sign[b] = 1;
    		}
    
    		int k = 0;
    		for (int i = 1; i < maxn; i++)
    		{
    			if (sign[i] && root[i] == i) // 判断根节点数目
    				k++;
    
    			if (k > 1) flag = 0;
    		}
    
    		if (flag) printf("Yes
    ");
    		else printf("No
    ");
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    Python os模块的使用
    数据分析 关于基础组件与介绍
    [SRH.Docker] HBase Java 第一天学习记录
    eclipse创建android项目失败的问题 [ android support library ]
    mysql学习总结
    celery的定时运用
    django认证
    django离线插入测试数据
    关于使用git仓库的操作
    小程序笔记
  • 原文地址:https://www.cnblogs.com/LQ6H/p/12940539.html
Copyright © 2011-2022 走看看