1. 程式人生 > 實用技巧 >AcWing 237 並查集+離散化

AcWing 237 並查集+離散化

https://www.acwing.com/problem/content/239/
並查集思路很平常,本題的坑點是資料範圍很大,要先進行離散化。其中對於本題在離散化時不用儲存原序列的大小,只需要保持一一對應即可,故用unordered_map進行離散化。

#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>
using namespace std;
const int N=2000010;
int n,m;
int p[N];
unordered_map<int,int> S;
struct Query
{
	int x,y,e;
}query[N];
int get(int x)
{
	if(S.count(x)==0) S[x]=++n;
	return S[x];
}
int find(int x)
{
	if(p[x]!=x) p[x]=find(p[x]);
	return p[x];
}
void merge(int x,int y)
{
	p[find(x)]=find(y);
}
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		n=0;
		S.clear();
		scanf("%d",&m);
		for(int i=1;i<=m;i++)
		{
			int x,y,e;
			scanf("%d%d%d",&x,&y,&e);
			query[i]={get(x),get(y),e};
		}
		
		for(int i=1;i<=n;i++) p[i]=i;
		
		for(int i=1;i<=m;i++)//合併所有相等條件 
			if(query[i].e==1)
			merge(query[i].x,query[i].y);
			
		int flag=1;
		for(int i=1;i<=m;i++)
		{
			if(query[i].e==0)
			{			
				if(find(query[i].x)==find(query[i].y))
				{
					flag=0;
					break;
				}
			}
		}
		if(flag) printf("YES\n");
		else printf("NO\n");
	}
}```