poj2236 Wireless Network 【并查集】
Wireless Network
题意
在一个网络中的共N台电脑都已经坏了,知道这些电脑的直角坐标,现在维修员对网络中的电脑一个一个维修,一边维修一边问某两台电脑是否可以通信了,通信双方电脑必须是已经修好了的,并且通信路线上每两台电脑的直接距离不能超过D。你需要回答维修员的问题。
分析
此题算是很典型的并查集算法,每次维修好一台电脑就把此台电脑和与其距离小于等于D的电脑合并在一起,也就是用并查集的join操作,然后师傅问两台电脑是否修好,就用find操作,就可以了。
AC 代码
#include <iostream> #include <algorithm> #include <stdio.h> using namespace std; typedef long long ll; int N,D; const int maxn = 1e3+10; struct node{ ll x,y; bool ok;//是否已经维修好 }no[1010]; int fa[maxn]; void init(){ for(int i = 1;i<=N;i++) fa[i] = i; } int find(int x){ if(x != fa[x]) return fa[x] = find(fa[x]); return fa[x]; } void join(int x,int y){ int fx = find(x),fy =find(y); if(fx!=fy) fa[fx] = fy; } bool dis(int a,int b){ if(!no[a].ok || !no[b].ok) return false; return (no[a].x-no[b].x)*(no[a].x-no[b].x) + (no[a].y-no[b].y)*(no[a].y-no[b].y) <= D*D; } int main(){ cin>>N>>D; init(); ll x,y; for(int i = 1;i<=N;i++){ scanf("%lld %lld",&x,&y); no[i] = {x,y,false}; } char op[2];int id1,id2; while(~scanf("%s",op)){ if(*op == 'O'){ scanf("%d",&id1); if(no[id1].ok) continue;//如果已经修好了,就不用修了 no[id1].ok = true; for(int i = 1;i<=N;i++){ if(i!=id1 && dis(i,id1)) join(i,id1); } }else{ scanf("%d%d",&id1,&id2); if(find(id1) != find(id2)) puts("FAIL"); else puts("SUCCESS"); } } return 0; }