51nod1515 明辨是非 并查集 + set
一开始想的时候,好像两个并查集就可以做......然后突然懂了什么....
相同的并查集没有问题,不同的就不能并查集了,暴力的来个set就行了.....
合并的时候启发式合并即可做到$O(n \log^2 n)$
如果打$splay$,那么启发式合并可以做到$O(n \log n)$
#include <set> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; extern inline char gc() { static char RR[23456], *S = RR + 23333, *T = RR + 23333; if(S == T) fread(RR, 1, 23333, stdin), S = RR; return *S ++; } inline int read() { int p = 0, w = 1; char c = gc(); while(c > '9' || c < '0') { if(c == '-') w = -1; c = gc(); } while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc(); return p * w; } #define pc(o) *O ++ = o char WR[30000005], *O = WR; inline void write(int opt) { if(opt == 1) pc('Y'), pc('E'), pc('S'), pc('\n'); else pc('N'), pc('O'), pc('\n'); } #define ri register int #define sid 200050 set <int> f[sid]; int T[sid], n, tot; int x[sid], y[sid], p[sid], fa[sid]; inline int find(int o) { if(fa[o] == o) return o; return fa[o] = find(fa[o]); } int main() { n = read(); for(ri i = 1; i <= n; i ++) { x[i] = read(); y[i] = read(); p[i] = read(); T[++ tot] = x[i]; T[++ tot] = y[i]; } sort(T + 1, T + tot + 1); tot = unique(T + 1, T + tot + 1) - T - 1; for(ri i = 1; i <= n; i ++) { x[i] = lower_bound(T + 1, T + tot + 1, x[i]) - T; y[i] = lower_bound(T + 1, T + tot + 1, y[i]) - T; } for(ri i = 1; i <= tot; i ++) fa[i] = i; for(ri i = 1; i <= n; i ++) { int u = find(x[i]), v = find(y[i]); if(!p[i]) { if(u == v) write(-1); else write(1), f[u].insert(v), f[v].insert(u); } else { if(u == v) write(1); else if(f[u].count(v)) write(-1); else { write(1); if(f[u].size() > f[v].size()) swap(u, v); fa[u] = v; for(set <int> :: iterator it = f[u].begin(); it != f[u].end(); it ++) { int w = *it; f[w].insert(v); f[v].insert(w); } } } } fwrite(WR, 1, O - WR, stdout); return 0; }
喵喵喵?喵喵喵! 喵喵喵......