文章目录
一、题目
输入格式:
输出格式:
输入样例:
输出样例:
二、方法1
1、思路
用到了并查集的思维,主要还是靠递归求和。
其实第一眼看见这个题,第一反应是dfs,但是又不完全算dfs。
2、代码
#include<stdio.h>
#define max 100005
int n, k;
double z, r;
int i, j; // 遍历
int id; // 徒弟名
double sum = 0; // 总功力
double value[max] = { 0 }; // 存放每个人的功力
int pre[max], s[max] = { 0 }; // pre->关系,s->武功被放大的倍数
double get_value(int x, double r); // 获取x的功力
int main()
{
scanf("%d %lf %lf", &n, &z, &r);
value[0] = z;
for (i = 0; i < n; i++)
{
scanf("%d", &k);
// 为得道者
if (k == 0)
{
scanf("%d", &id);
// 记录武功被放大的倍数
s[i] = id;
}
else
{
for (j = 0; j < k; j++)
{
scanf("%d", &id);
// 与其师傅联系起来
pre[id] = i;
}
}
}
for (i = 0; i < n; i++)
{
// 得道者
if (s[i])
{
sum += get_value(i, r) * s[i];
}
}
printf("%d\n", (int)sum);
return 0;
}
double get_value(int x, double r)
{
if (value[x] == 0)
{
value[x] = (1 - r / 100) * get_value(pre[x], r);
}
return value[x];
}