描述
题解
很简单的一道题,不过出题有些坑了,一看题就知道,这是一个搜索问题,dfs、bfs 都可以用,存储树时我选择的是邻接表,但是却一直24分,拿不到25分。纠结死我了。后来了解到,问题出在 N 为 1 的时候,也就是说只有一个人,既是太师傅,又是得道者(这也太没溜了,一个徒弟也收不了还叫得道者),其实这个我早就想到了,只是有一点我感觉是这个题出的问题,因为题目中说了 Z 是太师傅的功力值,理论上讲,如果是这样的话,就算他是得到者也不能再翻倍了,因为他没有师傅,直接给定了他的功力,再翻倍怎么说得过去呢?我就是因为这个思维,无限24……后来一个朋友说,他也许是孙悟空一样的男人,一言不合就超赛,仔细一想,大概其他是弗利沙一样的男人吧!!!
代码
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
const int MAXN = 1e5 + 10;
vector<int> v[MAXN];
int N;
double Z, r;
double p[MAXN];
double sum = 0;
void dfs(int root)
{
for (int i = 0; i < v[root].size(); i++)
{
if (p[v[root][i]] != 1)
{
p[v[root][i]] = p[root] * r * p[v[root][i]];
sum += p[v[root][i]];
}
else
{
p[v[root][i]] = p[root] * r;
dfs(v[root][i]);
}
}
}
int main(int argc, const char * argv[])
{
// freopen("/Users/zyj/Desktop/input.txt", "r", stdin);
cin >> N >> Z >> r;
r = (100 - r) / 100;
for (int i = 0; i < N; i++)
{
p[i] = 1;
}
p[0] = Z;
int K, nt;
for (int i = 0; i < N; i++)
{
scanf("%d", &K);
if (K == 0)
{
scanf("%lf", p + i);
continue;
}
for (int j = 0; j < K; j++)
{
scanf("%d", &nt);
v[i].push_back(nt);
}
}
if (N == 1)
{
printf("%d\n", (int)(p[0] * Z));
return 0;
}
dfs(0);
printf("%d\n", (int)sum);
return 0;
}