信息学奥赛一本通评测系统P1336

恭喜你看到了这篇题解,他会让你避开很多坑(新手推荐,大佬提些建议嘛)

当然,我不想让大佬像下面这道题中大佬一样。[AHOI2017/HNOI2017]大佬 - 洛谷https://www.luogu.com.cn/problem/P3724
                                      1336:【例3-1】找树根和孩子


                                      时间限制: 1000 ms         内存限制: 65536 KB
                                              提交数: 12616     通过数: 6521

【题目描述】

给定一棵树,输出树的根root,孩子最多的结点max以及他的孩子。

【输入】

第一行:n(结点个数≤100≤100),m(边数≤200≤200)。

以下m行:每行两个结点x和y,表示y是x的孩子(x,y≤1000x,y≤1000)。

【输出】

第一行:树根:root;

第二行:孩子最多的结点max;

第三行:max的孩子(按编号由小到输出)。

【输入样例】

8 7
4 1
4 2
1 3
1 5
2 6
2 7
2 8

【输出样例】

4
2 
6 7 8

如果在考场上遇到了,那场考试一定很(妙极了)

这道题是树的基础例题,不过有三个bug

(到时候我会讲的)

废话不多说,马上开始!!!

因为这里的一个根有可能有很多节点所以……它来了它来了

结构体数组!!!

代码段如下:

struct node{
	int data;//数值
}a[101];//节点

把题目中的n,m,root,max,x,y定义好(顺便把输入写了)

int n,m,x,y,root,maxx=-1;
cin>>n>>m;
for(int i=0;i<m;i++)
{
	cin>>x>>y;
	a[x].data=y;
}

第一个bug:

这里只能存a[y]的父亲是x(很奇怪)

int n,m,x,y,root,maxx=-1;
cin>>n>>m;
for(int i=0;i<m;i++)
{
	cin>>x>>y;
	a[y].data=x;
}

第二个bug:

这里x或y超过n这题就无解!!!

下一步:找爸爸找根节点,根节点没有父亲节点,那么(我们把根节点的data设为x):a[x].data=0

不妨通过第二个bug和a[x].data=0可以推断出如下代码段:

for(int i=0;i<n;i++)
{
	if(a[i].data==0)
	{
		root=i;
		break;
	}
}
cout<<root<<endl;

是不是很简单?

接下来我们统计max

做一个统计(sum),每次比较取大值

嵌套循环,如果内者父亲的data是外者,那么sum++

(有点不好理解,不理解可以在聊天区写出来,但是作者不是经常来CSDN,不懂可以多思考一会儿,实在不行再提,ok?)

代码段如下:

int sum=0,t;
for(int i=0;i<n;i++)
{
	for(int j=0;j<n;j++)
		if(a[j].data==i)
			sum++;
	if(maxx<sum)
	{
		maxx=sum;
		t=i;
	}//maxx=maxx>sum?maxx:sum应该也行作者没试过(从if(maxx<sum)开始到这了换成maxx=maxx>sum?maxx:sum))
	sum=0;
}
cout<<t<<endl;

基本上难的地方就是这里了,接下来输出t的孩子们所有子节点

接下来,从小到大,不重不漏,a[i].data=0即可:

代码段如下(f这时这是判断打不打空格的了):

for(int i=0;i<n;i++)
{
	if(a[i].data==t)
	{
		if(f)
			cout<<" ";
		cout<<i;
		f++;
	}
}

完整代码:

#include<bits/stdc++.h>
using namespace std;
struct node{
	int data;
}a[101];
int main()
{
	int n,m,x,y,root,maxx=-1;
	cin>>n>>m;
	for(int i=0;i<m;i++)
	{
		cin>>x>>y;
		a[y].data=x;
	}
	for(int i=0;i<n;i++)
	{
		if(a[i].data==0)
		{
			root=i;
			break;
		}
	}
cout<<root<<endl;
	int f=0,t;
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)	
			if(a[j].data==i)
				f++;
		if(maxx<f)
		{
			maxx=f;
			t=i;
		}
		f=0;
	}
	
	cout<<t<<endl;
	f=0;
	for(int i=0;i<n;i++)
	{
		if(a[i].data==t)
		{
			if(f)
				cout<<" ";
			cout<<i;
			f++;
		}
	}
    return 0;
}

如果你是为了抄代码而来的,对不起,上面是错误代码,如果你仔细看了我的题解那可能会想:第三个bug呢?

它来了:

第三个bug:

循环必须从1开始!!!

(为了不让那些抄代码的直接点到,我就不做标题了)

AC代码:

#include<bits/stdc++.h>
using namespace std;
struct node{
	int data;
}a[101];
int main()
{
	int n,m,x,y,root,maxx=-1;
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		cin>>x>>y;
		a[y].data=x;
	}
	for(int i=1;i<=n;i++)
	{
		if(a[i].data==0)
		{
			root=i;
			break;
		}
	}
cout<<root<<endl;
	int f=0,t;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)	
			if(a[j].data==i)
				f++;
		if(maxx<f)
		{
			maxx=f;
			t=i;
		}
		f=0;
	}
	
	cout<<t<<endl;
	f=0;
	for(int i=1;i<=n;i++)
	{
		if(a[i].data==t)
		{
			if(f)
				cout<<" ";
			cout<<i;
			f++;
		}
	}
    return 0;
}

制作不易,不喜勿喷

关注一下,发现更多精彩内容!!!

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值