题目大意:一棵树,找出每个节点的层数,然后根据能量损失,计算出每个节点目前的能量,注意“得道者”的扩大倍数。(数据范围)
算法:bfs(队列实现)+vector建树
详细思路:读入一棵树,标记“得道者”,根据入度为0判断root,进行bfs,通过queue完成bfs,记录每一个节点的层数,遍历每个节点,判断“得道者”,使用pow或者快速幂算出节点能量,AC。
注意:
1、如果用for循环,考虑一条链的特殊情况,,会导致TLE,然后测试点6就tle了。
2、queue实现树的bfs遍历还是比较常用的,注意一下正确姿势。
代码如下:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
#define ll long long
#define N 100005
int n;
double z,r;
vector<int>V[N];
int flag[N],dep[N];
int inr[N];
void bfs(int x)
{
queue<int>Q;
Q.push(x);
while(!Q.empty())
{
int rr=Q.front();
Q.pop();
int tt=V[rr].size();
for(int i = 0;i < tt;i++)
{
int to=V[rr][i];
dep[to]=dep[rr]+1;
Q.push(to);
}
}
}
int main()
{
cin >> n >> z >> r;
for(int i = 0;i < n;i++)
{
int k;
cin >> k;
if(k==0)
{
int bei;
cin >> bei;
flag[i]=bei;
}else
{
for(int ii = 1;ii <= k;ii++)
{
int x;
cin >> x;
V[i].push_back(x);
inr[x]++;
}
}
}
int rt;
for(int i = 0;i < n;i++)
{
if(inr[i]==0)
{
rt=i;
break;
}
}
dep[rt]=0;
bfs(rt);
double ans=0;
for(int i = 0;i < n;i++)
{
if(flag[i])
{
double sum=z;
sum=z*pow(1.00-r/100,dep[i]);
/*for(int j = 1;j <= dep[i];j++)
{
sum*=(1.00-r/100);
}*/
ans+=sum*flag[i];
}
}
printf("%lld",(ll)ans);
return 0 ;
}