51Nod 1515(並查集、set、離散化)
阿新 • • 發佈:2017-05-29
() space 並查集 conn com i++ include int esp
//代碼還是YY學姐幫改的,自己從來沒有真正A過幾道題,不是看題解就是有BUG找不出,多久了還是改變不了這樣的現狀,或許ACM就是這麽篩選人的吧。從5.24到11.24,再到又一年的5.24,可感覺後者比前者過得快多了。多讀了一年的大學,完全沒有了時間概念,不知道現在到底是大幾了,不知道現在到底處在什麽位置,不知道畢業後到底從不從事IT這行,一切都是未知的。
題目鏈接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1515
思路:數字範圍為1e8,所以要先離散化,然後在每個連通塊的祖先節點用一個set維護,兩個聯通塊合並的時候對set作恰當處理。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N = 2e5 + 5; int father[N],r[N]; map <int,int> vis; set <int> s[N]; set <int> :: iterator it; struct node { int x,y,p; }q[N>>1]; int finds(int x) { if(father[x] != x) father[x] = finds(father[x]); return father[x]; } void connect(int a,int b) { if(r[a] > r[b]) { for(it = s[b].begin(); it != s[b].end(); it++) { int tmp = finds(*it); s[*it].erase(b); s[a].insert(tmp); s[tmp].insert(a); } father[b] = a; r[a]++; } else { for(it = s[a].begin(); it != s[a].end(); it++) { int tmp = finds(*it); s[*it].erase(a); s[b].insert(tmp); s[tmp].insert(b); } father[a] = b; r[b]++; } } int main() { int n,x,y,t = 1; scanf("%d",&n); for(int i = 1; i <= n; i++) { scanf("%d %d %d",&x,&y,&q[i].p); if(!vis[x]) { vis[x] = t; q[i].x = t++; } else q[i].x = vis[x]; if(!vis[y]) { vis[y] = t; q[i].y = t++; } else q[i].y = vis[y]; } for(int i = 1; i <= n; i++) { father[q[i].x] = q[i].x; father[q[i].y] = q[i].y; } for(int i = 1; i <= n; i++) { t = 0; x = finds(q[i].x); y = finds(q[i].y); if(q[i].p) { if(x == y) puts("YES"); else { if(s[x].count(y)) puts("NO"); else { puts("YES"); connect(x,y); } } } else { if(x == y) puts("NO"); else { puts("YES"); s[x].insert(y); s[y].insert(x); } } } return 0; }
51Nod 1515(並查集、set、離散化)