NOI2015 Day1 T1 程序自动分析

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


你可能感兴趣的:(NOI2015 Day1 T1 程序自动分析)