POJ 2236 - Wireless Network - Union-Find

 

POJ 2236  -  Wireless Network 

描述
东南亚发生地震。亚洲合作医疗队(ACM)已经用lap电脑建立了一个无线网络,但是一次意外的余震袭击,网络中的所有电脑都坏了。
电脑一台接一台地被修好了,网络逐渐又开始工作了。由于硬件的限制,每台计算机只能直接与距离它不超过d米的计算机通信。
但是每台计算机都可以看作是另外两台计算机之间通信的媒介,也就是说,如果计算机A和计算机B可以直接通信,或者有一台计算机C可以与A和B通信,那么计算机A和计算机B就可以通信。

在修复网络的过程中,工作人员可以随时进行两种操作,一种是修复一台计算机,另一种是测试两台计算机是否可以通信。你的工作是回答所有的测试操作。

输入
第一行包含两个整数N和d(1<=N<=1001,0<=d<=20000)。
这里N是计算机的数量,从1到N,D是两台计算机可以直接通信的最大距离。
在N行中,每个包含两个整数席,Y(0<=席,Yi=10000),这是n个计算机的坐标。
从第(N+1)行到输入的末尾,有一些操作,这些操作是逐个执行的。每行包含以下两种格式之一的操作:
1. "O p" (1<=p<=N),意思是修复计算机p。
2. "S p q" (1<=p,q<=N),意思是测试电脑p和q是否可以通信。
输入不超过300000行。

输出
对于每个测试操作,如果两台计算机可以通信,则打印“成功”,否则打印“失败”。

 

思路: 不要被坐标干扰,将坐标抽取为对象(对象中定义坐标及满足合并条件的方法),保存到数组中,用数组下标代替点,使用并查集思路解决

 
package basic_data_structure;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;
/**
 * 
 * @author XA-GDD
 * 
 ** 思路: 不要被坐标干扰,将坐标抽取为对象(对象中定义坐标及满足合并条件的方法),保存到数组中,用数组下标代替点,使用并查集思路解决
 *
 */
public class C_WirelessNetwork {

	static int N,d;
	static Computer [] comArr = new Computer[1003]; //保存电脑坐标
	static ArrayList<Integer> repairList;
	static int [] parent = new int[1003];
	
	public static void main(String[] args) throws IOException {
				
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		
		N = Integer.parseInt(st.nextToken());
		d = Integer.parseInt(st.nextToken());
		for(int i=1;i<=N;i++) {
			st = new StringTokenizer(br.readLine());
			comArr[i] = new Computer(Integer.parseInt(st.nextToken()),Integer.parseInt(st.nextToken()));
		}
		
		for(int i=1;i<=N;i++) {
			parent[i] = i;
		}
		
		repairList = new ArrayList<Integer>(); //已修复的电脑的编号
		while(br.ready()) {
			st = new StringTokenizer(br.readLine());
			String operationType = st.nextToken();
			if("O".equals(operationType)) {
				int index = Integer.parseInt(st.nextToken());
				repairList.add(index); //将修复的电脑添加到list中
				
				for(int i=0;i<repairList.size();i++) { //遍历所有已修复的电脑,与当前电脑是距离是否小于d,小于则可以通信,合并
					if(comArr[index].dis(comArr[repairList.get(i)])<=d) {
						union(index,repairList.get(i));
					}	
				}
			}else {
				System.out.println((find(Integer.parseInt(st.nextToken())) == find(Integer.parseInt(st.nextToken())))?"SUCCESS":"FAIL");
			}
		}
	}

 
	static void union(int a, int b) {
		int pa = find(a);
		int pb = find(b);
		if(pa==pb) {
			return;
		}
		if(pa>pb) {
			parent[pb] = pa;
		}else {
			parent[pa] = pb;
		}
	}
	
	static int find(int n) {
		if(parent[n] == n) return n;
		return parent[n] = find(parent[n]);
	}
}

class Computer{
	int x;
	int y;
	
	Computer(int x, int y) {
		this.x = x;
		this.y = y;
	}
	
	public double dis(Computer c) {
		return Math.sqrt((c.x-this.x)*(c.x-this.x)+(c.y-this.y)*(c.y-this.y));
	}
}
 

  

posted @ 2021-10-10 09:45  晓暮云  阅读(43)  评论(0)    收藏  举报