SW练习_POJ2236_无线网络电脑维修_union-find

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

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值