PAT

xiaoxiao2021-02-28  107

#include <iostream> #include <math.h> #include <string.h> using namespace std; int N,maxDepth=0,num=0; double P,r; struct Node { int father,depth; }node[100005]; bool isYezi[100005]; int Find(int v) { int depth=0; int x=v; while(node[x].father!=-1) { if(node[x].depth!=-1) { //cout<<"第"<<x<<"节点的depth="<<node[x].depth<<endl; return depth+node[x].depth-1; } x=node[x].father; depth++; } int temp=depth; while(v!=-1) { v=node[v].father; node[v].depth=temp--; //cout<<"node["<<v<<"].depth="<<temp+1<<endl; } return depth; } int main() { for(int i=0;i<100005;i++) node[i].depth=-1; memset(isYezi,true,sizeof(isYezi)); scanf("%d%lf%lf",&N,&P,&r); for(int i=0;i<N;i++) { scanf("%d",&node[i].father); if(node[i].father!=-1) isYezi[node[i].father]=false; } for(int i=0;i<N;i++) { if(isYezi[i]==true) { int depth=Find(i); if(maxDepth<depth) { num=1; maxDepth=depth; } else if(maxDepth==depth) num++; } } printf("%.2lf %d\n",P*pow(r/100+1, maxDepth),num); return 0; }

  

自己的思路做起来比较麻烦,最初的想法代码实现起来非常快,40行就解决了,用一个father数组来记录每个节点的父亲节点,因为这是一棵树,所以我们每次只要搜索某个节点的父亲节点,一直往上面搜,找到根节点结束,用depth来记录这次搜索的长度即可,但仅仅是这样的思路,会有四个点超时。

思考:其实我们做了很多不必要的搜索,比如非叶节点,一定不能得到最长的路径,所以非叶节点就不应该开始搜索,此时我们需要加入一个bool 数组isYezi来保存某个节点是否为叶子节点。优化之后还是有一个节点超时,那其实当我们对一个叶子结点进行搜索之后,这条路径上的节点的深度都已经被计算出来了,当下次对另外的叶子节点进行搜索时若再搜到这个点时,就不需要再往上搜索了,直接加上这个节点的深度即可。

经过两次优化,就可以通过所有的测试点了。

转载请注明原文地址: https://www.6miu.com/read-48851.html

最新回复(0)