题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5337
开始的时候就知道是二叉树的应用,开始深搜各种查找都试过了,就是不对
最后惊奇的发现,递归竟然解决了。。。但是期间遇到的编译器里的BUG也是让我醉了...
题目大意:
现在拥有好多的机器,但是机器的原材料可能是其他机器的生成物品,并且每台机器最多有两个其他机器产生的原材料,也可以没有
但是处了最后的一个生成产品的机器外都有输出,现在高度不限制,求如图最小的宽度
整体思路:
从根节点开始向下递归,查找小范围的时候的最小宽度,这样在递归的时候最后所组成的也就是最小的了;
但是在递归的时候注意是3中情况,叶子节点,只有一个孩子,有两个孩子(其中这里也有两种
如果左右的孩子相同就直接加一,不相同就取最大的那个)
在正确解法出现之前,试过各种的方式,但是都只是在小的范围里成立,但是其实是错误的...
在做本题的时候其实结构体也挺好的...
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int tree[10010][2];
// int sum1,sum2;
int dfs(int i){ //返回的包含自己在内和子节点最小宽度
int sum1,sum2; //注意此处千万能定义在函数外面,用了一下午的时间竟然查错是错在这里,啊啊啊啊啊啊啊啊啊啊???????
//咆哮一下,祭奠一下我失去的一下午的时间
if( tree[i][0]==0 && tree[i][1]==0 ) return 1;//如果是叶子节点
if(tree[i][0]&&!tree[i][1]) return dfs(tree[i][0]);//只有一个(左)孩子
// if(!tree[i][0]&&tree[i][1]) return dfs(tree[i][1]);//只有右孩子}
if( tree[i][0]!=0 && tree[i][1]!=0 )
{
sum1=dfs(tree[i][0]);
sum2=dfs(tree[i][1]);
if(sum1==sum2) return sum1+1;//相等的时候,宽度为其中一个+1
else return sum1>sum2?sum1:sum2;//不等的时候,宽度为大的
}
return 0;
}
int main(){
int n;
int i;
int q;
while(~scanf("%d",&n)){
memset(tree,0,sizeof(tree));
for(i=2;i<=n;i++){
scanf("%d",&q);
if(tree[q][0]==0) tree[q][0]=i;
else tree[q][1]=i;
}
int ans=dfs(1);
printf("%d\n",ans);
}
return 0;
}