1118 Birds in Forest (25 分)

44 篇文章 0 订阅

题目大意:给定若干个照片,照片树上有若干个鸟,判断有多少棵树和多少只鸟,然后给定若干个查询,判断两只鸟是否在一棵树上。

题目说到鸟的编号一定是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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值