ZOJ 3805 Machine(二叉树,递归)
题意:一颗二叉树,求 “ 宽度 ”
思路:递归,貌似这个思路是对的,先记下,但是提交时超时,
1.如果当前节点只有左孩子,那么当前宽度等于左孩子宽度
2.如果当前节点只有右孩子,那么当前宽度等于右孩子宽度
3.如果当前节点既有左孩子又有孩子
3.1两个孩子宽度相等,则当前宽度等于其中一个孩子宽度+1
3.2两个孩子宽度不等,则当前宽度等于两个孩子宽度中大的那一个
代码1:超时
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int tree[10010][2]; int sum; int dfs(int i){ if(tree[i][0]==0&&tree[i][1]==0) return 1; if(tree[i][0]&&!tree[i][1]) return sum=dfs(tree[i][0]);//只有左孩子 if(!tree[i][0]&&tree[i][1]) return sum=dfs(tree[i][1]);//只有右孩子 else if(dfs(tree[i][0])==dfs(tree[i][1])) return sum=dfs(tree[i][0])+1;//相等的时候,宽度为其中一个+1 else return sum=dfs(tree[i][0])>dfs(tree[i][1])?dfs(tree[i][0]):dfs(tree[i][1]);//不等的时候,宽度为大的 } int main(){ int n; int i; int q; while(~scanf("%d",&n)){ sum=0; 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; }
代码2:正确,代码1的超时原因是,在递归过程中,递归运算太多了,多了不少重复的运算
但是,以下正确代码更是蛋疼,有两个变量不能定义为全局变量,,,,啊啊啊啊啊,为啥啊,,,
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int tree[10010][2]; //int lsum,rsum; int dfs(int i){ int lsum,rsum;//无语,,这俩变量定义为全局就不对,,求解脱 if(tree[i][0]==0&&tree[i][1]==0) return 1; if(tree[i][0]&&!tree[i][1]){ // cout<<"1只有左孩子"<<endl; return dfs(tree[i][0]);//只有左孩子 } if(!tree[i][0]&&tree[i][1]){//此处代码不会运行,因为不存在只有右孩子的情况 // cout<<"2只有右孩子"<<endl; return dfs(tree[i][1]);//只有右孩子 } lsum=dfs(tree[i][0]); rsum=dfs(tree[i][1]); //cout<<"lsum "<<lsum<<" rsum "<<rsum<<endl; if(lsum==rsum) { // cout<<"3左右孩子相等"<<endl; // cout<<"lsum+1 "<<lsum+1<<endl; return lsum+1;//相等的时候,宽度为其中一个+1 } else { // cout<<"4左右孩子不相等"<<endl; return lsum>rsum?lsum:rsum;//不等的时候,宽度为大的 } } 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; }