#include #define REP(i,n) for(int i=0; i<(int)(n); i++) #include #include inline int getInt(){ int s; scanf("%d", &s); return s; } #include using namespace std; class UnionFind{ private: mutable vector id; int getId(int i) const{ if(i == id[i]) return i; return id[i] = getId(id[i]); } public: UnionFind(int size = 0){ init(size); } ~UnionFind(){} void init(int size){ id = vector(size); for(int i = 0; i < size; i++) id[i] = i; } void unite(int i, int j){ int next = min( getId(i), getId(j) ); id[getId(i)] = id[getId(j)] = next; } int operator [](int i) const{ return getId(i); } int count() const{ set s; for(int i = 0; i < (int)id.size(); i++) s.insert(getId(i)); return s.size(); } }; int l[100]; vector s[100]; int f[100]; pair dfs(int pos, int d = 0){ if(f[pos]) return make_pair(0, 0.); int cnt = 1; double ret = l[pos]; if(d) ret /= 2; f[pos] = 1; REP(i,s[pos].size()){ pair tmp = dfs(s[pos][i], 1); cnt += tmp.first; ret += tmp.second; } f[pos] = 0; return make_pair(cnt, ret); } int main(){ const int n = getInt(); UnionFind uf(n); REP(i,n){ l[i] = getInt(); const int ss = getInt() - 1; s[ss].push_back(i); uf.unite(i, ss); } vector cnts(n); REP(i,n) cnts[uf[i]]++; vector memo(n, 1e10); REP(i,n){ pair tmp = dfs(i); if(tmp.first == cnts[uf[i]]) memo[uf[i]] = min(memo[uf[i]], tmp.second); } double ans = 0; REP(i,n) if(uf[i] == i) ans += memo[i]; printf("%.1f\n", ans); return 0; }