数据范围一开始是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; }