记录一下求解代码
思路
- 并查集作为工具,每次输入新的一组数据时将所有辅助空间重置
- menton数组,minX,maxX来记录输入数据的最大值,最小值以及输入过的数据,因为数据输入并不是从一开始也不是n-m连续的
- 对于每一组数据 输入的每一对数据,先检验是否二者father是否相同,相同说明已经连通,再联通便会有两条路不符合题意,不同便进行连接。
- 输入完每组数据后,再次进行运行find函数,进行路径压缩。检查每个节点的father是否一致,不一致说明不符合题意。
//
// Created by 29273 on 2022-03-09.
//
#include "bits/stdc++.h"
using namespace std;
const int maxN = 1e3 + 10;
int n, m, flag;
int father[maxN], minX, maxX;
bool mention[maxN];
void Init() {
for (int i = 0; i < maxN; ++i) {
father[i] = i;
}
memset(mention, 0, sizeof mention);
minX = 100001;
maxX = 1;
flag = 1;
}
int find(int x) {
int r = x;
while (r != father[r]) //寻找根结点
r = father[r];
int i = x, j;
while (father[i] != r) //路径压缩
{
j = father[i];
father[i] = r;
i = j;
}
return r;
}
void Union(int x, int y) {
int dx = find(x);
int dy = find(y);
if (dx != dy) {
father[dx] = dy;
}
}
int main() {
Init();
while (scanf("%d %d", &n, &m) == 2) {
if (n == -1 && m == -1) break;
if (n == 0 && m == 0) {
for (int i = minX; i <= maxX; i++) {
if (mention[i]) {
find(i);
}
}
int fa = father[minX];
for (int i = minX + 1; i <= maxX; ++i) {
if (mention[i] && father[i] != fa) {
flag = 0;
break;
}
}
if (flag)
printf("1\n");
else
printf("0\n");
Init();
} else {
mention[n] = 1;
mention[m] = 1;
minX = min(minX, min(n, m));
maxX = max(maxX, max(n, m));
if (find(n) != find(m)) {
Union(n, m);
} else {
flag = 0;
}
}
}
return 0;
}