http://acm.pku.edu.cn/JudgeOnline/problem?id=1202

Пример решения на Pascal:

Код:
const
   N_MAX = 300;

type
   percent =  record ready : boolean; dig_no : word; digits : array[1..N_MAX] of byte end;

var
   n, k	  : word;
   m	  : longint;
   parent : array[1..N_MAX,1..2] of word;
   rel	  : array[1..N_MAX,1..N_MAX] of percent;
   anc	  : array[1..N_MAX,1..N_MAX] of boolean;
   { anc[a,b]: is b ancestor of a }

(* THE ARITHMETIC OF N_MAX-DIGIT NUMBERS *)

procedure percent_dump(var p : percent);
var
   i : word;
begin
   if p.digits[1] <> 0 then
   begin
      write(p.digits[1]);
      write(p.digits[2])
   end
   else if p.digits[2] <> 0 then
      write(p.digits[2]);
   write(p.digits[3]);
   if p.dig_no > 3 then
   begin
      write('.');
      for i := 4 to p.dig_no do
	 write(p.digits[i])
   end;
   writeln('%');
end; { percent_dump }

procedure percent_init(var p : percent; val : byte);
begin
   p.dig_no := 3;
   p.digits[1] := val div 100;
   p.digits[2] := (val mod 100) div 10;
   p.digits[3] := val mod 10;
end; { percent_init }

procedure percent_average(var p1, p2, p3 : percent);
{ The only non-trivial operation we need: p3 := (p1 + p2) / 2 }
var
   i, j	  : word;
   sum	  : byte;
   carry  : byte;
   dig_no : word;
begin
   if p1.dig_no > p2.dig_no then
   begin
      dig_no := p1.dig_no;
      for i := p2.dig_no+1 to dig_no do p2.digits[i] := 0
   end
   else
   begin
      dig_no := p2.dig_no;
      for i := p1.dig_no+1 to dig_no do p1.digits[i] := 0
   end;

   carry := 0;
   for i := 1 to dig_no do
   begin
      sum := p1.digits[i] + p2.digits[i];
      p3.digits[i] := (sum div 2) + carry;
      j := i;
      while (p3.digits[j] > 9) do 
      begin
	 inc(p3.digits[j-1]);
	 dec(p3.digits[j],10);
	 dec(j)
      end;
      carry := (sum mod 2)*5;
   end;
   p3.dig_no := dig_no;
   if carry > 0 then
   begin
      inc(p3.dig_no);
      p3.digits[p3.dig_no] := carry
   end;
   while (p3.dig_no > 3) and (p3.digits[p3.dig_no] = 0) do
     dec(p3.dig_no)
end; { percent_average }

procedure percent_copy(var p1, p2 : percent);
var
   i : word;
begin
   p2.ready := p1.ready;
   p2.dig_no := p1.dig_no;
   for i := 1 to p1.dig_no do
      p2.digits[i] := p1.digits[i]
end; { percent_copy }

(* THE ANCESTOR GRAPH *)

procedure compute_anc(a,x : word);
{ Simple dfs }
var
   i : word;
begin
   if parent[x,1] = 0 then exit;
   for i := 1 to 2 do
   if not anc[a,parent[x,i]] then
   begin
      anc[a,parent[x,i]] := true;
      compute_anc(a,parent[x,i])
   end
end; { compute_anc }

(* THE IMPLEMENTATION OF THE RECURSIVE FORMULA *)

procedure compute_rel(a, b : word);
var
   c :  word;
begin
   if rel[a,b].ready then exit;

   if anc[b,a] then { we cannot go up from the ancestor }
   begin c := a; a := b; b := c end;

   if (a = b) then
      percent_init(rel[a,b],100)
   else if (parent[a,1] <> 0) then
   begin
      compute_rel(parent[a,1],b);
      compute_rel(parent[a,2],b);
      percent_average(rel[parent[a,1],b],
      rel[parent[a,2],b],
      rel[a,b])
   end
   else if (parent[b,1] <> 0) then
   begin
      compute_rel(a,parent[b,1]);
      compute_rel(a,parent[b,2]);
      percent_average(rel[a,parent[b,1]],
      rel[a,parent[b,2]],
      rel[a,b])
   end
   else
      percent_init(rel[a,b],0);
   rel[a,b].ready := true;
   percent_copy(rel[a,b],rel[b,a]);
end; { compute_rel }

(* THE MAIN PROGRAM *)

var
   a, b	: word;
   i	: longint;

begin
   readln(n,k);
   for a := 1 to n do
   begin
      parent[a,1] := 0; parent[a,2] := 0;
   end;
   
   for i := 1 to k do
   begin
      read(a);
      readln(parent[a,1],parent[a,2]);
   end;

   for a := 1 to n do
      for b := 1 to n do
	 rel[a,b].ready := false;

   for a := 1 to n do
      for b := 1 to n do
	 anc[a,b] := false;
   for a := 1 to n do
      compute_anc(a,a);
   
   readln(m);
   for i := 1 to m do
   begin
      readln(a,b);
      compute_rel(a,b);
      percent_dump(rel[a,b]);
   end;
end.