#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来保存某个节点是否为叶子节点。优化之后还是有一个节点超时,那其实当我们对一个叶子结点进行搜索之后,这条路径上的节点的深度都已经被计算出来了,当下次对另外的叶子节点进行搜索时若再搜到这个点时,就不需要再往上搜索了,直接加上这个节点的深度即可。
经过两次优化,就可以通过所有的测试点了。