#include <iostream>
using namespace std;
int find_parent(int x, int* parent) {
while (parent[x] != -1)
x = parent[x];
return x;
}
/*
int find_parent(int x, int* parent) {
if (parent[x] == x)
return x;
return find_parent(parent[x], parent);
}
int find_parent(int x, int *parent) {
if (parent[x] != x)
parent[x] = find_parent(parent[x], parent);
return parent[x];
}
*/
//这个函数反正我是没用到,就是判断两个结点的根是不是相同,可以在union函数中调,用但是我觉得写的话也没几行没必要
bool isbrother(int x, int y, int* parent) {
return find_parent(x, parent) == find_parent(x, parent);
}
/*
int union_1(int x, int y, int* parent) {
int x_parent = find_parent(x, parent);
int y_parent = find_parent(y, parent);
if (x_parent == y_parent)
return 1; //x,y根节点相同,合并成功
parent[x_parent] = y_parent;
return 0; //x,y没有关系
}
*/
//路径压缩,用rank来记录x,y结点对应的深度
int union_2(int x, int y, int* parent, int* rank) {
x = find_parent(x, parent);
y = find_parent(y, parent);
if (x == y)
return 1;
if (rank[x] < rank[y])
parent[x] = y;
else {
parent[y] = x;
if (rank[x] == rank[y])
rank[x]++;
}
return 0;
}
int main() {
int num_point, num_ship; //这边我用了动态方法设置结点数(num_point)和边数(num_ship),当然也可以根据题目要求设置静态的
cin >> num_point >> num_ship;
int* parent = new int[num_point];
int* rank = new int[num_point];
memset(parent, -1, num_point * sizeof(int));
//for (int i = 0; i < num_point; ++i) { //对应另外两个find_parent函数
// parent[i] = i;
//}
memset(rank, 0, num_point * sizeof(int));
int** ship = new int* [num_ship];
for (int i = 0; i < num_ship; ++i)
ship[i] = new int[2];
for (int i = 0; i < num_ship; ++i)
for (int j = 0; j < 2; ++j)
cin >> ship[i][j];
for (int i = 0; i < num_ship; ++i) {
int x = ship[i][0];
int y = ship[i][1];
//if (union_1(x, y, parent)) {
if (union_2(x, y, parent,rank)) {
cout << "Find circle!" << endl;
return 0;
}
}
cout << "Failed find" << endl;
return 0;
}
并查集
最新推荐文章于 2024-07-29 20:58:50 发布