题解
并查集+离散化。
这题并查集使用起来有个小trick,就是先把e=1的先合并再考虑e=0的,
这样可以回避掉因为顺序不一导致的又合又分的情况。
第一次碰见离散化。大意是把大范围数转化为小范围的数,转化方法是
根据其在原数组内的相对位置。
例如
{ 9783, 123 , 31342432, 231324 }
->
{ 123, 9783, 231324, 31342432 }
->
{ 1, 2, 3, 4 }
ps: 离散的时候需要两个数组,一个记录,一个变化。
Code
#include <iostream>
#include <cstdio>
#include <fstream>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <cstdlib>
using namespace std;
const int N = 100002;
int n;
struct node{
int x,y,e;
}cot[N];
int f[N*10],book[N*30];
void init(){
memset(f,0,sizeof(f));
memset(book,0,sizeof(book));
memset(cot,0,sizeof(cot));
}
int findp(int x){
if(x!=f[x])
f[x]=findp(f[x]);
return f[x];
}
bool cmp(node &a,node &b){
return a.e>b.e;
}
int main()
{
int t;
cin>>t;
bool pr;
int a,b,e;
while(t--){
cin>>n;
init();
pr=false;
int tot=0;
for(int i=0;i<n;i++){
cin>>cot[i].x>>cot[i].y>>cot[i].e;
book[tot++]=cot[i].x;
book[tot++]=cot[i].y;
}
// 离散化 begin
sort(book,book+tot);
int span = unique(book,book+tot) - book;
for(int i=0;i<n;i++){
cot[i].x = lower_bound(book,book+span,cot[i].x) - book;
cot[i].y = lower_bound(book,book+span,cot[i].y) - book;
}
// end
sort(cot,cot+n,cmp);
for(int i=0;i<N*10;i++) f[i]=i;
for(int i=0;i<n;i++){
int ap=findp(cot[i].x);
int bp=findp(cot[i].y);
if(cot[i].e == 1){
f[ ap ] = bp;
}else{
if( ap==bp ){
cout<<"NO\n";
pr=true;
break;
}
}
}
if(pr) continue;
cout<<"YES\n";
}
return 0;
}