最近发现自己数据结构全部忘记基本,只能从头再补,此题是一道典型的并查集+离散化的题目。
题目:程序自动分析
做法:离散化+并查集
1、因为注意到数据的取值范围最大有
1
0
9
10^9
109,而又用到并查集来存储节点,所以先要进行离散化。总共有
1
0
6
10^6
106 次询问,因此最多也只会用到
2
×
1
0
6
2 \times10^6
2×106 个数字,数组范围可以满足。同时这里的离散化不需要满足保序性,所以用
m
a
p
map
map 就可以完成。
2、这道题目的并查集是很典型的并查集。只需要先处理相等的情况,然后判断不相等的情况会不会和原来冲突,冲突则有问题。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <unordered_map>
using namespace std;
const int N=1000010;
int p[N*2];
int n,tot;
int t;
struct query{
int x,y,e;
}q[N];
unordered_map<int,int> mp;
int get(int x){ //离散化
if(mp.count(x)==0) mp[x]=++tot;
return mp[x];
}
int find(int x){
if(p[x]!=x) p[x]=find(p[x]);
return p[x];
}
int main(){
cin>>t;
while(t--){
tot=0;
mp.clear(); //*
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x,y,e;
scanf("%d%d%d",&x,&y,&e);
q[i]={get(x),get(y),e};
}
for(int i=1;i<=tot;i++) p[i]=i;
for(int i=1;i<=n;i++){
if(!q[i].e) continue;
p[find(q[i].y)]=find(q[i].x);
}
bool flag=false;
for(int i=1;i<=n;i++){
if(q[i].e) continue;
if(find(q[i].x)==find(q[i].y)){
flag=true;
break;
}
}
if(flag) cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}
return 0;
}