并查集——poj2236(带权并查集)
Posted GGBeng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了并查集——poj2236(带权并查集)相关的知识,希望对你有一定的参考价值。
题意:给定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(带权并查集)的主要内容,如果未能解决你的问题,请参考以下文章
带权并查集(含种类并查集)经典模板 例题:①POJ 1182 食物链(经典)②HDU - 1829 A bug's life(简单) ③hihoCoder 1515 : 分数调查(示例代码(代