HBCPC 20202 Ending
题目
7-4 Ending
作者 ICPC Team
单位 北京邮电大学
Rilly is playing an interesting game during COVID-19 quarantine. The game has n different events, and players start from event 1.
Except the ending event (numbered n), each event has several follow-up events. While being in a specific event, you can advance to one of its follow-up events with a given probability. If you successfully advance to one of the follow-up events, you can never go backward. Or, if you have unluckily failed to advance, you can try to move to other follow-up events. If you have tried all follow-ups and still failed, your game is over.
Rilly asked Northy, the game developer, to tell him all events and their follow-ups, along with probability to successfully advance, so that you can help him decide his best chance of getting to the ending event.
Input Format
First line contains two integers n,m(2≤n≤5×104,1≤m≤105), the number of events and the number of follow up relations.
Then m lines follow, each of which consists of three numbers x,y,p(1≤x,y≤n,0≤p≤100), denoting that you may advance from event x to event y with probability p%.
It is guaranteed that you can not return to a passed event through the follow-up relations.
Output Format
Print a single decimal number, the maximum probability of reaching the ending event. You answer is considered correct if the absolute or relative error doesn't exceed 10−6.
Sample Input
4 4
1 2 50
1 3 50
2 4 30
3 4 70
Sample Output
0.425000
代码长度限制
16 KB
时间限制
1000 ms
内存限制
512 MB
思路
设\(f(u)\) 表示从\(u\)到终点的概率, 则
上述式子表示从\(u\)到\(v_i\)的概率
Code
#include <bits/stdc++.h>
using i64 = long long;
const int N = 5e5 + 10, M = 2e5 + 10;
int n, m;
int h[N], e[M], ne[M], idx;
double w[M];
std::unordered_map<int, double> hash;
struct node {
int id;
double val;
bool operator>(const node t) const {
return val > t.val;
}
};
void add(int a, int b, double c) {
ne[idx] = h[a], h[a] = idx, e[idx] = b, w[idx ++] = c;
}
double dfs(int u) {
if (u == n) return 1;
if (hash.count(u)) return hash[u];
std::vector<node> f;
for (int i = h[u]; ~i; i = ne[i]) {
int v = e[i];
f.push_back({i, dfs(v)});
}
/*
f[cnt] * w[h[u] + cnt - 1]] * \prod (1 - w[(h[u], h[u] + cnt - 2)])
*/
std::sort(f.begin(), f.end(), std::greater<node>());
// std::cout << u << "<-point\n";
// for (int i = 0; i < f.size(); i ++) {
// std::cout << f[i].val << " \n"[i == (int) f.size() - 1];
// }
double ans = 0, t = 1;
for (int i = 0; i < f.size(); i ++) {
double val = f[i].val;
int id = f[i].id;
ans += val * w[id] * t;
// std::cout << val << " " << w[h[u] + id] << "\n";
t *= (1 - w[id]);
}
// std::cout << ans << "<-res\n";
return hash[u] = ans;
}
int main() {
memset(h, -1, sizeof h);
std::cin >> n >> m;
while (m --) {
int x, y;
double c;
std::cin >> x >> y >> c;
c *= 0.01;
add(x, y, c);
}
printf("%.6lf", dfs(1));
}