这道NOI的题看起来很水,我这不到NOIP的水平的人都能A掉。
但毕竟水平洼,交到第4次才A,原因是,map的操作掌握的不熟练。
这道题用我学长的话来说就是并查集乱搞,用某大大大神犇的话说就是用并查集瞎**乱搞。
对,这道NOI的题,只需要一个并查集就可以。
不过一开始看到i,j的范围10亿还给吓到了,数组开不了这么大,不过又有n的范围是10万,也就是说最多有20万个数,还数上了相同的。
所以简单的离散化就可以。
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <map>
#define M 100005
using namespace std;
int t, n, flag;
int fa[M*2], s[M*2];
struct query{ //用结构体的话这份代码在COGS上是过不了的,会T,只要把结构体去掉,换成3个数组就好了
int i, j, e;
}q[M];
int find(int x){return x == fa[x] ? x : fa[x] = find(fa[x]);}
int main()
{
scanf("%d", &t);
while(t--){
flag = 1;
memset(s, 0, sizeof s);
scanf("%d", &n);
for(int k = 1; k < M*2; k++) fa[k] = k;
for(int k = 1; k <= n; k++){
scanf("%d %d %d", &q[k].i, &q[k].j, &q[k].e);
s[++s[0]] = q[k].i;
s[++s[0]] = q[k].j;
}
sort(s+1, s+s[0]);
map <int, int> m;
for(int k = 1; k <= s[0]; k++)
m.insert(pair<int,int>(s[k], k)); // 就是这里,s[k]与k的位置不能搞反,才能通过s[k]检索k
for(int k = 1; k <= n; k++)
if(q[k].e) {
int a = find(m[q[k].i]), b = find(m[q[k].j]);
if(a != b) fa[a] = b;
}
for(int k = 1; k <= n; k++)
if(!q[k].e){
int a = find(m[q[k].i]), b = find(m[q[k].j]);
if(a == b) {printf("NO\n"); flag = 0; break;}
}
if(flag) printf("YES\n");
}
return 0;
}