POJ2236ワイヤレスネットワーク

题目链接:POJ2236ワイヤレスネットワーク
の制限時間:10000MSメモリ制限:65536kも
合計提出:49928受理:20443

説明
アンの地震が東南アジアで行われます。ACM(アジア間連携医療チーム)がラップコンピュータとワイヤレスネットワークを設定しましたが、予想外の余震は攻撃、ネットワーク内のすべてのコンピュータがすべて壊れていました。コンピュータは、一つ一つを修復され、そしてネットワークが徐々に再び仕事を始めました。なぜならハードウェア制限しにより、各コンピュータは、直接遠いそれからDメートル以下であるコンピュータと通信することができます。しかし、すべてのコンピュータは、コンピュータAとコンピュータBが直接通信できる場合、コンピュータAとコンピュータBが通信することができると言うことであるか、またはその両方Aと通信することができるコンピュータ・Cが2台の他のコンピュータとの間の通信の仲介、とみなすことができるとB.

2台のコンピュータが通信できる場合は、ネットワークを修復する過程では、労働者は、すべての瞬間において業務の2種類を取り、コンピュータを修理、またはテストすることができます。あなたの仕事は、すべてのテスト作業に答えることです。

入力は、
最初の行は二つの整数NおよびD(1 <= Nを<= 1001 0 <= D <= 20000)を含みます。ここでNは、1からNまで番号付けされているコンピュータの数であり、Dは、2台のコンピュータが直接通信可能な最大距離です。次のNラインにおいて、それぞれがN個のコンピュータの座標を2つの整数のXI、YI(0 <= XI、YI <= 10000)を含みます。(N + 1)番目の行からの入力の終わりに、一枚ずつ行われる動作があります。各行は、次の2つの形式のいずれかでの操作が含まれています。

  1. 「OのP」(1 <= p <= N)、コンピュータpを修復する手段。
  2. 「SのPQ」(1 <= P、Q <= N)、コンピュータpおよびqが通信できるかどうかをテストする手段。

入力は300000行を超えることはありません。

出力
各テスト動作の場合は、2台のコンピュータが通信できる場合、「SUCCESS」を印刷し、または「FAIL」ではない場合。

サンプル入力

4 1
0 1
0 2
0 3
0 4
O 1
O 2
O 4
S 1 4
O 3
S 1 4

サンプル出力

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

チャー変数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