数据范围一开始是10^10,吓了一跳,后来改成10^9还是不会,想做个暴力的全连通图。后来别人说是并查集才反应过来。
先离散化一下,然后最多就剩20w个数,用并查集维护。最后for判断一下就行了。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cctype>
#include<cstdlib>
#define rep(i ,n) for(int i=0; i < n; ++i)
#define clr(x ,c) memset(x, c, sizeof(x))
using namespace std;
const int maxn = 200005;
struct T {
int x;
T* next;
} *head[ maxn ] , pool[ maxn ] , *pt;
void add( int u , int v ) {
pt -> x = v;
pt -> next = head[ u ];
head[ u ] = pt++;
}
inline int read() {
char c = getchar();
int ans = 0;
for( ; ! isdigit( c ) ; c = getchar() );
for( ; isdigit( c ) ; c = getchar() )
ans = ans * 10 + c - '0';
return ans;
}
int fa[ maxn ];
int find( int x ) {
return x == fa[ x ] ? x : fa[ x ] = find( fa[ x ] );
}
struct Q {
int x , y;
bool type;
} q[ maxn ];
int id[ maxn << 1 ];
int main(){
freopen("prog.in", "r", stdin);
freopen("prog.out", "w", stdout);
int t = read();
while( t-- ) {
int cnt = 0;
pt = pool;
int n = read();
rep( i , n ) {
Q &p = q[ i ];
id[ cnt++ ] = p.x = read();
id[ cnt++ ] = p.y = read();
p.type = read();
}
sort( id , id + cnt );
cnt = unique( id , id + cnt ) - id;
rep( i , cnt ) fa[ i ] = i;
clr( head , 0 );
rep( i , n ) {
Q* p = q + i;
if( p -> type )
fa[ find( lower_bound( id , id + cnt , p -> x ) - id ) ] =
find( lower_bound( id , id + cnt , p -> y ) - id );
else
add( lower_bound( id , id + cnt , p -> x ) - id ,
lower_bound( id , id + cnt , p -> y ) - id );
}
bool ans = true;
rep( i , cnt ) {
for( T* p = head[ i ] ; p ; p = p -> next ) {
if( find( i ) == find( p -> x ) ) {
ans = false;
break;
}
}
if( ! ans ) break;
}
printf( ans ? "YES\n" : "NO\n" );
}
return 0;
}