我用from数字记录每一个节点的父亲节点,这样来求层数。但这样的做法需要优化,不然会超时。优化的三个方便如下:
- 优化1:已经求出第几层的可以直接用
- 优化2:求出某个节点层数,回溯回去继续求出它所有父亲节点层数
- 优化3:发现某个节点已求得情况下也不需要再求了
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e+5+10;
int from[maxn];
int level[maxn] = {0};
int main(int argc, char const *argv[])
{
fill(from, from+maxn, -1);
memset(level, 0, sizeof(level));
int n;
double p, r;
scanf("%d %lf %lf", &n, &p, &r);
int root;
for (int i = 0; i < n; ++i)
{
scanf("%d", &from[i]);
if(from[i]==-1) root=i;
}
for (int i = 0; i < n; ++i)
{
int t = 0;
int id = i;
if(level[id]>0) continue;
while(id!=root)
{
// 优化1:已经求出第几层的可以直接用
if(level[id]>0)
{
t += level[id];
break;
}
id = from[id];
t++;
}
level[i] = t;
// 优化2:求出某个节点层数,回溯回去继续求出它所有父亲节点层数
int temp = t;
id = i;
while(id!=root)
{
id = from[id];
// 优化3:发现某个节点已求得情况下也不需要再求了
if(level[id]>0) break;
temp --;
level[id] = temp;
}
}
int maxLevel = 0;
for (int i = 0; i < n; ++i)
{
if(level[i]>maxLevel)
{
maxLevel = level[i];
}
}
int count = 0;
for (int i = 0; i < n; ++i)
{
if(level[i]==maxLevel) count++;
}
printf("%.2f %d\n", p*pow(1+r/100, maxLevel), count);
return 0;
}