Wireless Network(POJ 2236)

来源:互联网 发布:http 文件 json 上传 编辑:程序博客网 时间:2024/06/06 02:18

Wireless Network

              Time Limit: 10000MS Memory Limit: 65536K

Description
An earthquake takes place in Southeast Asia. The ACM (Asia Cooperated Medical team) have set up a wireless network with the lap computers, but an unexpected aftershock attacked, all computers in the network were all broken. The computers are repaired one by one, and the network gradually began to work again. Because of the hardware restricts, each computer can only directly communicate with the computers that are not farther than d meters from it. But every computer can be regarded as the intermediary of the communication between two other computers, that is to say computer A and computer B can communicate if computer A and computer B can communicate directly or there is a computer C that can communicate with both A and B.
In the process of repairing the network, workers can take two kinds of operations at every moment, repairing a computer, or testing if two computers can communicate. Your job is to answer all the testing operations.

Input
The first line contains two integers N and d (1 <= N <= 1001, 0 <= d <= 20000). Here N is the number of computers, which are numbered from 1 to N, and D is the maximum distance two computers can communicate directly. In the next N lines, each contains two integers xi, yi (0 <= xi, yi <= 10000), which is the coordinate of N computers. From the (N+1)-th line to the end of input, there are operations, which are carried out one by one. Each line contains an operation in one of following two formats:
1. “O p” (1 <= p <= N), which means repairing computer p.
2. “S p q” (1 <= p, q <= N), which means testing whether computer p and q can communicate.
The input will not exceed 300000 lines.

Output
For each Testing operation, print “SUCCESS” if the two computers can communicate, or “FAIL” if not.

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

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

这个题是简单的并查集题目

AC的代码

#include <stdio.h>#include <math.h>int set[2][1010];int pre[1010];int rank[1010];int find(int x) //递归方式{    //查找元素x所在的集合,同时压缩寻找所经过的路径    //函数运行完后的效果是所经过的结点都指向x所找到的祖先    if(x != pre[x])        pre[x] = find(pre[x]);    return pre[x];}void merge(int x, int y){    /*将两个集合的元素合并成一个集合*/    x = find(x);    //查找x所在的集合    y = find(y);    //查找y所在的集合    if(x == y)        return;     //如果x和y在同一个集合中则不需要合并    /*按秩合并:将秩小的合并到大的集合中(即将矮的树合并到高的树)*/    if(rank[x] < rank[y])        pre[x] = y;    else{        pre[y] = x;        if(rank[x] == rank[y])            rank[x]++;    }}int main(void){    int n, d;    int i, j, k;    int a, b;    char ch;    scanf("%d%d", &n, &d);    for(int i = 1; i <= n; i++){        /*将要用到的数组初始化*/        pre[i] = i;   //初始时每个结点的祖先是自己        rank[i] = 0;  //初始时树的高度为0        set[0][i] = set[1][i] = 0;    }    for(i = 1; i <= n; i++)        scanf("%d%d", &set[0][i], &set[1][i]);    while(scanf("%c", &ch) != EOF){        switch(ch){            case 'O':                scanf("%d", &j);                rank[j] = 1;                for(i = 1; i <= n; i++){                    if(rank[i]){ /*只有结点修复后,才能被连接*/                        a = set[0][j]-set[0][i];                        b = set[1][j]-set[1][i];                        if(a*a + b*b <= d*d){                            merge(i, j);                        }                    }                }                break;            case 'S':                scanf("%d%d", &j, &k);                if(find(j) == find(k))                    printf("SUCCESS\n");                else                    printf("FAIL\n");                break;        }    }    return 0;}
原创粉丝点击