Skip to content

Instantly share code, notes, and snippets.

@asi1024
Created October 11, 2016 05:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save asi1024/a7301e68385fd813b2f9674dc1562036 to your computer and use it in GitHub Desktop.
Save asi1024/a7301e68385fd813b2f9674dc1562036 to your computer and use it in GitHub Desktop.
#include <bits/stdc++.h>
#define REP(i,n) for(int i=0;i<(int)(n);i++)
#define ALL(x) (x).begin(),(x).end()
using namespace std;
using ld = long double;
struct Edge{ int src, dest; };
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
void add_edge(Graph &g, int from, int to) {
g[from].push_back((Edge){from, to});
}
int scc(Graph &graph, vector<int> &cmp) {
int V = graph.size();
vector<vector<int>> g(V), rg(V);
vector<int> vs;
vector<bool> used(V, false);
cmp.resize(V);
REP(i,V) {
for (Edge e: graph[i]) {
g[i].push_back(e.dest);
rg[e.dest].push_back(i);
}
}
function<void(int)> dfs = [&g, &vs, &used, &dfs](int v) {
used[v] = true;
for (int i: g[v]) if (!used[i]) dfs(i);
vs.push_back(v);
};
function<void(int,int)> rdfs = [&rg, &cmp, &used, &rdfs](int v, int k) {
used[v] = true; cmp[v] = k;
for (int i: rg[v]) if (!used[i]) rdfs(i, k);
};
REP(v,V) if (!used[v]) dfs(v);
used = vector<bool>(V, false);
reverse(ALL(vs));
int k = 0;
for(int i: vs) if (!used[i]) rdfs(i, k++);
return k;
}
int main() {
int N;
while (cin >> N, N) {
vector<ld> p(N);
Graph g(N);
REP(i,N) {
cin >> p[i];
int m, a;
cin >> m;
REP(j,m) {
cin >> a;
add_edge(g, i, a - 1);
}
}
vector<int> cmp;
int K = scc(g, cmp);
vector<int> is_ok(K, 1);
for (const auto &es: g)
for (auto &&e: es)
if (cmp[e.src] != cmp[e.dest])
is_ok[cmp[e.dest]] = 0;
vector<ld> prod(K, 1.0);
REP(i,N) prod[cmp[i]] *= p[i];
ld res = 1;
REP(i,K) if (is_ok[i]) res *= 1 - prod[i];
cout << setprecision(9) << fixed << res << endl;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment