东方博宜——谁的孙子最多

东方博宜

树及树的应用

1775. 谁的孙子最多(https://oj.czos.cn/lists/display?id=1775&lid=25&cid=82

问题描述

给定一棵树,其中 1 号结点是根结点,问哪一个结点的孙子结点最多,有多少个。(孙子结点,就是儿子结点的儿子结点。)

输入

第一行一个整数 N(N≤10000),表示树结点的个数。

此后 NN 行,第 ii 行包含一个整数 Ci​,表示 i 号结点儿子结点的个数,随后共Ci​ 个整数,分别表示一个 i 号结点的儿子结点(结点编号在 1∼N 之间)。

输出

一行两个整数,表示孙子结点最多的结点,以及其孙子结点的个数,如果有多个,输出编号最小的(本题测试数据确保有解)。

样例

输入
5
2 2 3
1 4
0
1 5
0
输出
1 1

解析:构建树,寻找“孙子”最多的节点

解法1

结构体构建树

代码如下:

#include<bits/stdc++.h>
using namespace std;
struct node{
	int father;//父亲是谁
    int son[101];//儿子是谁
    int s;//儿子个数
    int s1;//孙子个数
}t[1001];
int main()
{
	int i,j,n,x,y,maxn=0,t1=0,c=0;
	cin>>n;
	for(i=1;i<=n;i++)
	{
		cin>>x;
		for(j=1;j<=x;j++)
		{
			cin>>y;
			t[i].s++;
			t[i].son[t[i].s]=y;
			t[t[i].son[t[i].s]].father=i;
			//构建父子关系
		}
	}
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=t[i].s;j++)
		{
			if(t[i].son[j]!=0)
			{
				t[i].s1=t[i].s1+t[t[i].son[j]].s;//孙子的个数=主角的所有儿子 的儿子的个数
			}
		}
	}
	for(i=1;i<=n;i++)
	{
		if(t[i].s1>maxn)
		{
			maxn=t[i].s1;
			t1=i;//标记
		}
	}
	cout<<t1<<" "<<t[t1].s1;
}
/*
:D
*/

解法2

向量构建树

代码如下:

#include<bits/stdc++.h>
using namespace std;
vector<int> c[100005];//儿子
int f[100005];//父亲
int main()
{
	int i,j,n,x,y,maxn=-1,t1=0,s;
	cin>>n;
	for(i=1;i<=n;i++)
	{
		cin>>x;
		for(j=1;j<=x;j++)
		{
			cin>>y;
			c[i].push_back(y);
			f[y]=i;
            //构建父子关系
		}
	}
	for(i=1;i<=n;i++)
	{
		s=0;//记得赋初值
		for(j=0;j<c[i].size();j++)
		{
			s=s+c[c[i][j]].size();//累加求和 
			//cout<<c[c[i][j]].size()<<" ";
		}
		if(s>maxn)//找最大值
		{
			maxn=s;
			t1=i;//注意!!i不要写成s!
		}
		//cout<<endl;
	}
	cout<<t1<<" "<<maxn;
}
/*
:D
5
2 2 3
1 4
0
1 5
0

         1
       2   3
     4
   5
*/

附记:

呜呜呜

不小心把i写成s了

if(s>maxn)
{
	maxn=s;
    t1=s;//!!
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值