You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
2.1 KiB
92 lines
2.1 KiB
#include <bits/stdc++.h>
|
|
|
|
using namespace std;
|
|
|
|
#pragma region 并查集模板
|
|
int p[101]; //存储元素的父节点
|
|
int Rank[101]; //存储树的高度(秩)
|
|
//建立并查集
|
|
void Build(int n) {
|
|
for (int i = 1; i <= n; ++i) {
|
|
p[i] = i; //父结点是元素自身
|
|
}
|
|
}
|
|
|
|
//查找根结点//路径压缩
|
|
int Find(int x) {
|
|
if (p[x] != x)
|
|
p[x] = Find(p[x]);
|
|
return p[x];
|
|
}
|
|
|
|
//按秩合并集合
|
|
void Union(int x, int y) {
|
|
x = Find(x);
|
|
y = Find(y);
|
|
if (Rank[x] < Rank[y]) p[x] = y;
|
|
else {
|
|
p[y] = x;
|
|
if (Rank[y] == Rank[x]) Rank[x]++;
|
|
}
|
|
}
|
|
|
|
#pragma endregion 并查集模板
|
|
|
|
int main() {
|
|
//输入+输出重定向
|
|
freopen("../1416.txt", "r", stdin);
|
|
|
|
int n, m;
|
|
cin >> n >> m;
|
|
//建立并查集
|
|
Build(n);
|
|
|
|
//合并集合
|
|
for (int i = 1; i <= m; ++i) {
|
|
int u, v;
|
|
cin >> u >> v;
|
|
//国家的较量首先从势力上进行比较,吞并国家多的能打赢吞并国家少的。
|
|
//如果两个国家的吞并的国家相同,就根据国家头目的编号来判断,我们假设编号大的国家能打得过编号小的国家。
|
|
//谁来合并谁?
|
|
int u1 = Find(u);
|
|
int uCount = 0;
|
|
|
|
int v1 = Find(v);
|
|
int vCount = 0;
|
|
|
|
for (int j = 0; j < 101; ++j) {
|
|
if (p[j] == u1) uCount++;
|
|
if (p[j] == v1) vCount++;
|
|
}
|
|
|
|
if (uCount > vCount) {
|
|
Union(u1, v1);
|
|
}
|
|
if (uCount < vCount) {
|
|
Union(v1, u1);
|
|
}
|
|
if (uCount == vCount) {
|
|
if (u > v) Union(u1, v1);
|
|
else Union(v1, u1);
|
|
}
|
|
}
|
|
|
|
int q;
|
|
cin >> q;
|
|
for (int i = 1; i <= q; ++i) {
|
|
int s;
|
|
cin >> s;
|
|
int p = Find(s);
|
|
//计算有多少个
|
|
int count = 0;
|
|
for (int j = 1; j <= n; ++j) {
|
|
if (Find(j) == p) count++;
|
|
}
|
|
cout << p << " " << count << endl;
|
|
}
|
|
|
|
//关闭文件
|
|
fclose(stdin);
|
|
return 0;
|
|
}
|