HDU_1272 小希的迷宫 ( 并查集判环 | 注意不连通的点 )

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_44510468/article/details/102733702

文章目录


题目连接 poj

题意

给一个无向图,
如果 连通 并且 无环 , 输出 Yes,
否则 No

题解

先贴一个玄学错误, 这份代码改下万能头在 hdu 上交 c++ 是 47ms 过了的, 交 g++ 是 wa
要想交 g++ 需要把判断连通的时候注释掉break
在这里插入图片描述

古怪的输入格式

先用并查集判环, 如果有环直接标记, 读完数据后输出 No, 这种情况表容易处理
如果标记是无环, 那么需要判断数据给出的图是否连通, 也就是判断并查集个数, 一个并查集那么这个图是连通的输出Yes, 否则 No

tips : 在读数据的同时需要 合并两个顶点, 还需要标记这两个点是数据给出的点( 点并不连续, 如样例图一缺少1号顶点 )

代码

#include <bits/stdc++.h> 
using namespace std;
#define rg register 
#define sc scanf 
#define pf printf 
typedef long long ll;



class DisjointSet {
public:
	static const int MAXN = 1e5 + 100;
	int n;
	int root[MAXN];
	DisjointSet ( ) {};
	DisjointSet ( int _n ) : n ( _n ) {};
	void INI ( int n ) {
		this->n = n;
		for ( int i = 0; i <= n; ++i ) root[i] = i;
	}
	int GET ( int x ) {
		return root[x] == x ? x : root[x] = GET ( root[x] );
	}
	bool MERGE ( int x, int y ) {
		int rx = GET ( x ), ry = GET ( y );
		if ( rx == ry ) return false;
		root[ry] = rx; return true;
	}
}ds;

bool isVertex[ds.MAXN];

int main ( ) {  // freopen( "F:\\in\\.txt" , "r" , stdin ); 

	int u, v;
	while ( ~sc( "%d%d", &u, &v ) ) {
		if ( u==-1 && v==-1 ) break;

		ds.INI ( ds.MAXN );
		memset ( isVertex, false, sizeof( isVertex ) );

		bool hasLoop = false;
		while ( 1 ) {
			if ( u==0 && v==0 ) break;

			isVertex[u] = true, isVertex[v] = true;
			if ( !ds.MERGE( u,  v ) ) // 没有融合成功那一定是根相同, 即有环
				hasLoop = true;
			sc( "%d%d", &u, &v );
		}

		if ( hasLoop==true )
			pf ( "No\n" );
		else {
			int sum = 0; // 统计并查集个数, 以确定图是否连通
			for ( int i = 0; i <= ds.MAXN; ++i ) 
				if ( isVertex[i] && ds.root[i]==i ) {
					sum++;
					if ( sum>1 ) break; // 交 g++ 需要注释掉这一行, 玄学错误, 给爷整懵了 ...
				}
			pf( "%s\n", sum>1 ? "No" : "Yes" );
		}
	}




	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44510468/article/details/102733702