题目链接: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 ",ans); } return 0; }