1. 程式人生 > 其它 >POJ 2236 - Wireless Network - Union-Find

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));
	}
}