hdu 1272 并查集判无向环 输入坑点

题意:给出若干个无向边,问是否是一棵树。

题解:并查集

1.并查集。(1)若新加边的两个端点有共同的根节点,那么假如这条边后就成环。

                 (2)若加入边过少会产生多棵树。

2.输入说明的是:每个测例以0 0结束,且点编号从1开始。意思是加入这个测例有点那么至少为1,可以没有房间,即直接0 0结束。在代码中已标注。这真是个坑点!!!!!!

#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#define N 100005
using namespace std ;
int pre[N] ;
int n , m ;
vector <int> room ;
int find(int x)
{
	int temp ;
	temp = x ;
	while(pre[x] != x)
	   x = pre[x] ;
	if(pre[temp] != x) // 压缩路径,提高效率。 
	   pre[temp] = x ; // 压缩路径就是把每个结点直接指向根节点,避免重复向上查找 
	return x ;
}
void join(int a , int b)
{
	int i , j ;
	int u , v ;
	int dis ;
    u = find(a) ;
    v = find(b) ;
    if(u == v)
       return ;
    pre[u] = v ;
}
int main()
{
	int i , j , k ;
	int p , q ;	
	int ans ;
	int t ;
	bool flag ;
	bool vis[N] ;
	while(scanf("%d%d" , &p , &q) && !(p == -1 && q == -1))
	{
		memset(vis , 0 , sizeof(vis)) ;
		flag = 1 ;
		for(i = 1 ; i <= N - 5 ; i ++)
		       pre[i] = i ;
		join(p , q) ;
		room.clear() ;
		if(!vis[p])
		{
			vis[p] = 1 ;
			room.push_back(p) ;
		}
		if(!vis[q])
		{
			vis[q] = 1 ;
			room.push_back(q) ;
		}
		if(p == 0 && q == 0)//输入坑点!!!!!! 
		{
			printf("Yes\n") ;
			continue ;
		}
		while(scanf("%d%d" , &p , &q) && !(p == 0 && q == 0))
	    {	
	        if(!vis[p])
		    {
			   vis[p] = 1 ;
			   room.push_back(p) ;
		    }
		    if(!vis[q])
		    {
			   vis[q] = 1 ;
			   room.push_back(q) ;
		    }
	        if(!flag)
	           continue ;
		    if(find(p) == find(q))
			{
			  flag = 0 ;
			  continue ;	
			}	 
		    join(p , q) ;
	    }
	    ans = 0 ;
	    for(i = 0 ; i < room.size() ; i ++)
	       if(pre[room[i]] == room[i])
	       	  ans ++ ;
	    if(flag && ans == 1)
	       printf("Yes\n") ;
	    else
	       printf("No\n") ;
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值