union的部分还没有考虑清楚,需要再调试一下
package info.frady.algo;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
meng3.wei 2020.05.12
Sample Input
4 1
0 1
0 2
0 3
0 4
O 1
O 2
O 4
S 1 4
O 3
S 1 4
Sample Output
FAIL
SUCCESS
*/
public class POJ2236 {
public static int N;
public static int D;
public static List<Ponnt> points;
public static int[] pid;
public static boolean[] repair;
public static boolean logger=false;
public static void main(String[] args) throws Exception{
points=new ArrayList<Ponnt>();
Scanner reader=new Scanner(System.in);
//BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
//String[] str=reader.readLine().split(" ");
String[] str=reader.nextLine().split(" ");
N=Integer.parseInt(str[0]);
D=Integer.parseInt(str[1]);
if(logger) System.out.printf("一共有 %d 个电脑,网络的覆盖距离是 %d \n",N,D);
pid=new int[N+1];
repair=new boolean[N+1];
for (int i = 0; i <N+1 ; i++) {
pid[i]=i;
}
points.add(new Ponnt(0,-1,-1));
for (int i = 1; i <=N ; i++) {//接收N个节点的坐标
//str=reader.readLine().split(" ");
str=reader.nextLine().split(" ");
int x=Integer.parseInt(str[0]);
int y=Integer.parseInt(str[1]);
Ponnt p=new Ponnt(i,x,y);
points.add(p);
}
String s;
//while((s=reader.readLine())!=null){
if(logger) System.out.printf("开始接受电脑的维修和连接数据\n");
while(reader.hasNext()){
s=reader.nextLine();
str=s.split(" ");
if(str[0].equals("O")){//操作
int index=Integer.parseInt(str[1]);//本次修好的节点
repair[index]=true;
Ponnt p=points.get(index);//P是本次修改好的
if(logger) System.out.printf("本次修好了电脑 %d\n",index);
for (int j = 1; j <points.size() ; j++) {
Ponnt q=points.get(j);
if( p.index!=q.index && repair[q.index] && !connected(p.index,q.index) && isNear(p,q)){
if(logger) System.out.printf(" %d 在 %d 的附近,并且没有连接过,已经维修过了,可以连接一下\n",p.index,index);
union(p,q);
}
}
}else{//S 判断
int pindex=Integer.parseInt(str[1]);
int qindex=Integer.parseInt(str[2]);
if(logger) System.out.printf(" 判断 %d 和 %d 是否可以连接 \n",pindex,qindex);
if(connected(pindex,qindex)){
System.out.println("SUCCESS");
}else{
System.out.println("FAIL");
}
}
}
reader.close();
}
public static int find(int p){
int tmp=p;
while(pid[p]!=p){
p=pid[p];
}
while(pid[tmp]!=p){//此处进行了路径的压缩,此题目不压缩也可以AC 压缩 16157MS->15860MS
tmp=pid[tmp];
pid[tmp]=p;
}
return p;
}
public static void union(Ponnt p,Ponnt q){
int m=find(p.index);//保存p的祖先节点
int n=find(q.index);//保存q的祖先节点
if(m==n){
return;
}
if(p.index<=q.index){//p的数字小,把q挂载到p上m
pid[n]=m;
}else{
pid[m]=n;
}
}
public static boolean connected(int p,int q){
int m=find(p);
int n=find(q);
return m==n;
}
public static boolean isNear(Ponnt p,Ponnt q){
long dis=(p.x-q.x)*(p.x-q.x)+(p.y-q.y)*(p.y-q.y);
return dis<=(D*D);
}
}
class Ponnt{
public int index;
public int x;
public int y;
public Ponnt(int index,int x,int y){
this.index=index;
this.x=x;
this.y=y;
}
}