#include #include #include #include #include using namespace std; using ll = long long; struct SCC{ int n; vector> to, revto, group; vector used, order, id; SCC(int n=0):n(n), to(n), revto(n), used(n), id(n, -1){} void add_edge(int u, int v){ to[u].push_back(v); revto[v].push_back(u); } void dfs1(int u){ used[u]=1; for(auto p:to[u])if(!used[p]) dfs1(p); order.push_back(u); } void dfs2(int u, int i){ id[u]=i; group[i].push_back(u); for(auto p:revto[u])if(id[p]==-1) dfs2(p, i); } int build(){ //成分数 for(int i=0; i> contra(){ int c=group.size(); vector> ans(c); vector> seen(c); for(int i=0; i, vector>> topo(bool rev=false){ int c=group.size(); auto cont=contra(); vector degin(c); for(int i=0; i q; for(int i=0; i ans; while(!q.empty()){ int now=q.front(); q.pop(); ans.push_back(now); for(int p:cont[now]){ degin[p]--; if(degin[p]==0) q.push(p); } } if(rev){ reverse(ans.begin(), ans.end()); vector> revto(c); for(int i=0; i> n; SCC scc(n); vector level(n); for(int i=0; i> level[i] >> s; s--; scc.add_edge(s, i); } int m=scc.build(); auto [p, to]=scc.topo(); vector seen(n); auto dfs=[&](auto dfs, int now, int par=-1)->double { double sum=0, mi=1e9; double ans=0; seen[now]=1; for(auto q:scc.group[now]){ sum+=level[q], mi=min(mi, level[q]); } for(auto ni:to[now]){ ans+=dfs(dfs, ni, now); } if(par==-1) sum-=mi, sum/=2.0, sum+=mi; else sum/=2.0; return ans+sum; }; double ans=0; for(int i=0; i