洛谷P2147[SDOI2008]洞穴勘测

题目

LCT,或者并查集水过。

首先并查集这道题不能路径压缩,因为路径压缩是为了用牺牲一些信息的方法来加快速度,可是这道题我们需要这个信息,所以不能路径压缩。

剩下的操作就只剩下了暴力并查集,而每次查询前都要使u所在的树换根,使u换为该树的根,可以方便查询。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define int long long
#define N 4011
using namespace std;
int n, m, fa[401100];
inline int query(int u, int v)
{	
	while (v && u != v) 
	{
		v = fa[v];
		if (v == u)
			return 1;
	}
	if (u == 0) return 1;
	if (v == u) return 1;
	return 0;
}	
inline void connect(int u, int v)
{
	fa[u] = v;
}
inline void destroy(int u, int v) 
{
	fa[v] = 0; 
}
signed main()	
{
	scanf("%lld%lld", &n, &m);
	for (int i = 1; i <= m; i++)
	{		
		string s; int u, v, temp = 0, u1, ha;
		cin >> s;
		scanf("%lld%lld", &u, &v);
		u1 = u;
		while (u1)//换根操作,使u为u所在的树的根
		{	
			ha = fa[u1]; 
			fa[u1] = temp; temp = u1; u1 = ha;
		}	
		if (s == "Connect")
		   	connect(u, v);
		if (s == "Destroy")
			destroy(u, v); 
		if (s == "Query")
		{	
			if (query(u, v)) 
				printf("Yes
");
			else 
				printf("No
");	
		}	
	}		
	return 0;
}
原文地址:https://www.cnblogs.com/liuwenyao/p/10993671.html