题目大意:给定若干个照片,照片树上有若干个鸟,判断有多少棵树和多少只鸟,然后给定若干个查询,判断两只鸟是否在一棵树上。
题目说到鸟的编号一定是1到某个数连续的,所以鸟的数量就是最大值编号,如果这没读懂没关系,直接用set存每只鸟,最后的长度就是数量。
鸟的数量解决了,树的数量其实就是求连通块的数量,这里就可以用dfs,bfs,或者并查集来实现,但是后面我们需要来查询两只鸟是否在同一棵树,所以本题用并查集写方便。
#include <iostream>
#include <vector>
using namespace std;
const int N = 10010;
int n,x,a,b,num,p[N];
vector<int>v[N];
int find(int x)
{
if(p[x] != x) p[x] = find(p[x]);
return p[x];
}
int main()
{
int tt;
cin >> tt;
for(int k = 0; k < tt; k ++)
{
cin >> n;
for(int i = 0; i < n; i ++)
{
cin >> x;
v[k].push_back(x);
num = max(x,num);
}
}
for(int i = 1; i <= num; i ++) p[i] = i;
int cur = num;//连通块的数量
for(int i = 0; i < tt; i ++)
for(int j = 0; j < v[i].size() - 1; j ++)
{
int a = find(v[i][j]),b = find(v[i][j + 1]);
if(a != b) p[a] = b,cur --;
}
cout << cur << ' ' << num << '\n';
int op;
cin >> op;
while(op --)
{
cin >> a >> b;
if(find(a) == find(b)) puts("Yes");
else puts("No");
}
return 0;
}