POJ2236 Wireless Network

题目链接:POJ2236 Wireless Network
Time Limit: 10000MS Memory Limit: 65536K
Total Submissions: 49928 Accepted: 20443

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

程序说明:

并查集,每次修好电脑时循环所有的电脑,把修好的且距离小于d的合并。
另外注意输入时的空格和回车(因为这个小细节卡了好久…)

代码如下:

#include <iostream>
#include <cstdio>
#define MAX 1001
using namespace std;
struct point {
	int x, y;
} p[MAX + 1];
//par数组记录根,rank数组记录树的高度,vis数组标记是否已经修好 
int par[MAX + 1], rank[MAX + 1], vis[MAX + 1];
int n, d, dis;
void init() {
	for(int i = 1; i <= n; i++) {
		par[i] = i;
		rank[i] = 0;
		vis[i] = 0;
	}
}
int find(int x) {
	if(par[x] == x)
		return x;
	else
		return par[x] = find(par[x]);
}
void merge(int x1, int y1) {
	dis = (p[x1].x - p[y1].x) * (p[x1].x - p[y1].x) + (p[x1].y - p[y1].y) * (p[x1].y - p[y1].y);
	x1 = find(x1);
	y1 = find(y1);
	if(x1 == y1)
		return;
	if(rank[x1] < rank[y1] && dis <= d * d)
		par[x1] = y1;
	else if(rank[x1] >= rank[y1] && dis <= d * d){
		par[y1] = x1;
		if(rank[x1] == rank[y1])
			rank[x1]++;
	}
}
bool same(int x, int y) {
	return find(x) == find(y) ? true : false;
}
int main() {
	scanf("%d%d", &n, &d);
	init();
	char ch[2];
	for(int i = 1; i <= n; i++) {
		scanf("%d%d", &p[i].x, &p[i].y);
	}
	while(~scanf("%s", ch)) {
		if(ch[0] == 'O') {
			int k;
			scanf("%d", &k);
			vis[k] = 1;
			for(int i = 1; i <= n; i++) {
				//不在一个集合里并且已经被修好了 
				if(!same(i, k) && i != k && vis[i] == 1) {
					merge(i, k);
				}
			}
		}
		else {
			int p, q;
			scanf("%d%d", &p, &q);
			if(same(p, q))
			//在同一个集合里 
				printf("SUCCESS\n");
			else
				printf("FAIL\n");
		}
	}	
	return 0;
} 

之前声明了一个char型变量ch,但由于scanf会吸收缓冲区的回车和空格导致不能正常输出。下面的代码是改过之后的,有效解决了上述问题。

#include <iostream>
#include <cstdio>
#define MAX 1001
using namespace std;
struct point {
	int x, y;
} p[MAX + 1];
//par数组记录根,rank数组记录树的高度,vis数组标记是否已经修好 
int par[MAX + 1], rank[MAX + 1], vis[MAX + 1];
int n, d, dis;
void init() {
	for(int i = 1; i <= n; i++) {
		par[i] = i;
		rank[i] = 0;
		vis[i] = 0;
	}
}
int find(int x) {
	if(par[x] == x)
		return x;
	else
		return par[x] = find(par[x]);
}
void merge(int x1, int y1) {
	dis = (p[x1].x - p[y1].x) * (p[x1].x - p[y1].x) + (p[x1].y - p[y1].y) * (p[x1].y - p[y1].y);
	x1 = find(x1);
	y1 = find(y1);
	if(x1 == y1)
		return;
	if(rank[x1] < rank[y1] && dis <= d * d)
		par[x1] = y1;
	else if(rank[x1] >= rank[y1] && dis <= d * d){
		par[y1] = x1;
		if(rank[x1] == rank[y1])
			rank[x1]++;
	}
}
bool same(int x, int y) {
	return find(x) == find(y) ? true : false;
}
int main() {
	scanf("%d%d", &n, &d);
	init();
	char ch;
	for(int i = 1; i <= n; i++) {
		scanf("%d%d", &p[i].x, &p[i].y);
	}
	while(~scanf("%c", &ch)) {
		if(ch == 'O') {
			int k;
			scanf("%d", &k);
			vis[k] = 1;
			for(int i = 1; i <= n; i++) {
				//不在一个集合里并且已经被修好了 
				if(!same(i, k) && i != k && vis[i] == 1) {
					merge(i, k);
				}
			}
		}
		else if(ch == 'S'){
			int p, q;
			scanf("%d%d", &p, &q);
			if(same(p, q))
			//在同一个集合里 
				printf("SUCCESS\n");
			else
				printf("FAIL\n");
		}
	}	
	return 0;
} 
发布了44 篇原创文章 · 获赞 0 · 访问量 845

猜你喜欢

转载自blog.csdn.net/Komatsu_1137/article/details/104051215
今日推荐