Sweety

Practice makes perfect

导航

ZOJ 5337 Machine

Posted on 2014-11-22 16:59  蓝空  阅读(110)  评论(0编辑  收藏  举报

题目链接: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;
}