zoukankan      html  css  js  c++  java
  • 【并查集】poj 2236 Wireless Network

    题目描述:

    http://poj.org/problem?id=2236

     

    中文大意:

    东南亚发生地震,工作人员进行网络修复。

    由于硬件限制,每台计算机只能与 (0,d] 范围内的计算机进行通信,但却可以充当中介,即如果计算机 C 可以与计算机 A 和计算机 B 进行通信,则计算机 A 和计算机 B 可以进行通信。

    在修复网络的过程中,工作人员可以随时执行两种操作:修复一台计算机、测试两台计算机是否可以通信。

    我们的工作是回答所有测试操作。

     

    思路:

    一个计算机网络就是一个集合。

    每修复一台计算机,便尝试将它与 (0,d] 范围内的所有已经被修复的计算机进行连接。

    两台计算机可以通讯的前提条件是:在同一个集合中,且均已被修复。

     

    代码:

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<math.h>
    using namespace std;
    
    //记录各节点的位置信息 
    struct node{
        int x,y;
    }pos[1002];
    
    int sets[1002];//各节点的所属集 
    int height[1002];//各集合的树高 
    bool repaired[1002] = {false};//是否被修理
    
    int n,d;
    
    //初始化,各节点属于独立的集合 
    void init(){
        for(int i=1;i<=n;i++){
            sets[i] = i;
            height[i] = 1;
        }
    }
    
    //查询节点 x 的所属集 
    int find(int x){
        //寻找根节点 
        int root = x;
        while(root != sets[root]){
            root = sets[root];
        } 
        
        //路径压缩:将路径上节点的所属集修改为根节点 
        int i = x;
        while(sets[i] != root){
            int j = sets[i];
            sets[i] = root;
            i = j;
        }
        return root;
    }
    
    //合并 
    void union_set(int x, int y){
        //寻找节点 x 的所属集 
        x = find(x);
        //寻找节点 y 的所属集 
        y = find(y);
        
        //若两个节点的所属集树高相同,则将 x 的所属集并到 y 的所属集 
        if(height[x] == height[y]){
            sets[x] = y;
            height[y]++;
        }//否则,将矮树并到高树,高树的树高保持不变 
        else if(height[x] > height[y]){
            sets[y] = x;
        }
        else{
            sets[x] = y;
        }
    }
    
    //计算两个节点之间的距离 
    int cal_dis(int x, int y){
        int dis_x = pos[x].x - pos[y].x;
        int dis_y = pos[x].y - pos[y].y;
        return dis_x*dis_x + dis_y*dis_y;
    }
    
    int main(){
        scanf("%d %d", &n, &d);
        init();
        
        for(int i=1;i<=n;i++){
            scanf("%d %d", &pos[i].x, &pos[i].y);
        }
        
        char c;
        int x,y;
        getchar();//scanf("%c", &c) 会读入回车 
        while(~scanf("%c", &c)){
            if(c == 'O'){
                scanf("%d", &x);
                repaired[x] = true;
                
                //将节点 x 合并到 (0,d] 范围内的集合中 
                for(int i=1;i<=n;i++){
                    if(i == x || !repaired[i]){
                        continue;
                    }
                    
                    int dis = cal_dis(x, i);
                    if(dis <= d*d){
                        union_set(x, i);
                    }
                }
            }
            else if(c == 'S'){
                scanf("%d %d", &x, &y);
                
                //两台计算机均被修理,且在同一个通讯网络中 
                if(repaired[x] && repaired[y] && find(x) == find(y)){
                    printf("SUCCESS
    ");
                }
                else{
                    printf("FAIL
    ");
                }
            }
            getchar();
        }
    } 
    作者:老干妈就泡面
    本文版权归作者和博客园共有,欢迎转载,但请给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
  • 相关阅读:
    react-native-开发环境搭建
    深入理解js中的立即执行函数(function(){…})()
    html-webpack-plugin详解
    window.getComputedStyle——ref
    react-hot-loader 的配置【局部刷新】--{create-react-app}
    es6 export、import
    echarts 金字塔
    JFinal源码详解
    如何使用JFinal开发javaweb
    MySQL如何修改密码
  • 原文地址:https://www.cnblogs.com/bjxqmy/p/14482543.html
Copyright © 2011-2022 走看看