题目大意:给出N张照片,每张照片上有一些鸟的编号(<10^4),同一张照片上的鸟被认为属于同一棵树,求出最大有多少棵树和多少只鸟,并判断给出的两只鸟是否属于同一棵树。
常规并查集问题,如果不用路径压缩的话测试点3会超时。
AC代码:
#include <vector>
#include <cstdio>
using namespace std;
const int MAXN = 10010;
vector<int> parent(MAXN);
int findParent(int p)
{
int a = p;
while(p != parent[p])
{
parent[p] = parent[parent[p]];
p = parent[p];
}
return p;
}
void unionElement(int a, int b)
{
int aRoot = findParent(a);
int bRoot = findParent(b);
parent[aRoot] = bRoot;
}
int main()
{
int N;
scanf("%d", &N);
vector<bool> hasAppeared(MAXN, 0);
vector<bool> roots(MAXN, 0);
int birdsCnt = 0;
int rootsCnt = 0;
for (int i = 0; i < MAXN; ++i)
parent[i] = i;
for (int i = 0; i < N; ++i)
{
int cnt;
scanf("%d", &cnt);
int id;
scanf("%d", &id);
if(!hasAppeared[id])
{
hasAppeared[id] = true;
birdsCnt++;
}
for (int j = 1; j < cnt; ++j)
{
int other;
scanf("%d", &other);
if(!hasAppeared[other])
{
hasAppeared[other] = true;
birdsCnt++;
}
unionElement(id, other);
}
}
for (int i = 0; i < MAXN; ++i)
{
if(hasAppeared[i])
{
int iRoot = findParent(i);
if(!roots[iRoot])
{
rootsCnt++;
roots[iRoot] = true;
}
}
}
printf("%d %d\n", rootsCnt, birdsCnt);
int Q;
scanf("%d", &Q);
for (int query = 0; query < Q; ++query)
{
int u, v;
scanf("%d%d", &u, &v);
if(findParent(u) == findParent(v)) printf("Yes\n");
else printf("No\n");
}
return 0;
}
本文介绍了一个使用并查集数据结构解决鸟群分类问题的算法。通过处理N张照片上的鸟编号,该算法能够找出最大鸟群数量及鸟总数,并判断任意两只鸟是否属于同一群。代码实现中,采用路径压缩优化,有效避免了超时问题。

331

被折叠的 条评论
为什么被折叠?



