using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.IO;
class Myon
{
public Myon() { }
public static int Main()
{
new Myon().calc();
return 0;
}
bool[] used;
int ret;
int[] L, S;
List<int>[] rev;
void calc()
{
Scanner cin = new Scanner();
int n = cin.nextInt();
L = new int[n];
S = new int[n];
for (int i = 0; i < n; i++)
{
L[i] = cin.nextInt();
S[i] = cin.nextInt() - 1;
}
int[] innum = new int[n];
rev = new List<int>[n];
for (int i = 0; i < n; i++)
{
rev[i] = new List<int>();
}
for (int i = 0; i < n; i++)
{
innum[S[i]]++;
rev[S[i]].Add(i);
}
used = new bool[n];
ret = 0;
while (true)
{
bool flag = false;
for (int i = 0; i < n; i++)
{
if (innum[i] == 0 && !used[i])
{
ret += L[i];
used[i] = true;
innum[S[i]]--;
flag = true;
}
}
if (!flag) break;
}
for (int i = 0; i < n; i++)
{
if (!used[i])
{
int temp = dfs(i);
ret += temp;
}
}
Console.WriteLine("{0:0.0}", ret / 2.0);
}
int dfs(int a)
{
if (used[a]) return 99999999;
used[a] = true;
int r = L[a];
ret += L[a];
foreach (var item in rev[a])
{
r = Math.Min(dfs(item), r);
}
return r;
}
}
class Scanner
{
string[] s;
int i;
char[] cs = new char[] { ' ' };
public Scanner()
{
s = new string[0];
i = 0;
}
public string next()
{
if (i < s.Length) return s[i++];
do
{
s = Console.ReadLine().Split(cs, StringSplitOptions.RemoveEmptyEntries);
} while ((s.Length == 1 && s[0] == "") || s.Length == 0);
i = 0;
return s[i++];
}
public int nextInt()
{
return int.Parse(next());
}
public long nextLong()
{
return long.Parse(next());
}
public double nextDouble()
{
return double.Parse(next());
}
}