並查集——poj2236(帶權並查集)
阿新 • • 發佈:2017-08-11
algorithm blog oid poj2236 stream 命令 net 最大 spa
題目:Wireless Network
題意:給定n臺已損壞計算機的位置和計算機最遠通信距離d,然後分別根據命令執行以下兩種操作:
- "O p" (1 <= p <= N) :表示修理計算機p;
- "S p q" (1 <= p, q <= N) :表示檢測計算機p和計算機q能否通信。
輸出:能通信則輸出"SUCCESS",否則輸出"FAIL"
題解:
帶權並查集還是那個重要的知識點——關系。
此題,我們使用一個repair數組存儲每臺電腦的狀態(損壞還是好的)
然後就是對每次修好的電腦對其它已經修好的電腦遍歷,如果距離小於等於最大通信距離就將他們合並。之後判斷2臺電腦是不是一個集合中就行了。
代碼:
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; int n,k; bool repair[1005]; //為真則修好了 struct point{ int pre; int x,y; }c[1005]; void init() { for(int i=1;i<=n;i++){ c[i].pre = i; repair[i] = false; } } int find(int x) { if(x==c[x].pre) return x; c[x].pre = find(c[x].pre); return c[x].pre; } void unite(const point p1, const point p2) { int root1, root2; root1 = find(p1.pre); root2 = find(p2.pre); if(root1 != root2) if((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y) <= k * k) c[root2].pre = root1; } int main() { cin>>n>>k; init(); for(int i=1;i<=n;i++){ scanf("%d%d",&c[i].x,&c[i].y); } char s[5]; int a,b; while(scanf("%s",s)!=EOF){ if(s[0]==‘O‘){ scanf("%d",&a); repair[a] = true; for(int i=1;i<=n;i++){ if(i!=a && repair[i]){ unite(c[a],c[i]); } } } else{ scanf("%d%d",&a,&b); if(find(a) == find(b)){ printf("SUCCESS\n"); } else printf("FAIL\n"); } } return 0; }
並查集——poj2236(帶權並查集)