bzoj3143

之前我们曾经用dp解决过数学期望问题,这次我们用的是解方程的方法
首先在编号之前,肯定要求出每条边的期望经过次数
然后可以转化为求边端点的期望次数
这种做法我一开始接触是noip2013的初赛问题求解,是类似的思想
当出现循环无法用dp解决时,我们考虑列方程
设pi为点i的期望经过次数
则容易得到pi=sigma(pj/dj) dj表示出度,j是与i相邻的点
特殊的p1=1+sigma(pj/dj) pn=0(因为到n就停止了)
于是我们可以得到一个方程组,这样就可以用高斯消元求解
解出之后就能求出边的期望经过次数了,然后贪心分配编号即可

 1 var w:array[0..510,0..510] of longint;
 2     a:array[0..510,0..510] of double;
 3     x,y:array[0..300010] of longint;
 4     c,p:array[0..300010] of double;
 5     d:array[0..510] of longint;
 6     i,j,k,n,m:longint;
 7     ans:double;
 8 
 9 procedure swap(var a,b:double);
10   var c:double;
11   begin
12     c:=a;
13     a:=b;
14     b:=c;
15   end;
16 
17 procedure calc;
18   var i,j,k,w:longint;
19   begin
20     for i:=1 to n do
21     begin
22       w:=i;
23       for k:=i+1 to n do
24         if abs(a[k,i])>abs(a[w,i]) then w:=k;
25       if w<>i then
26       begin
27         for j:=1 to n+1 do
28           swap(a[w,j],a[i,j]);
29       end;
30       for k:=i+1 to n do
31         for j:=n+1 downto i do
32           a[k,j]:=a[k,j]-a[i,j]*a[k,i]/a[i,i];
33     end;
34     p[n]:=0;
35     for i:=n-1 downto 1 do
36     begin
37       for j:=i+1 to n do
38         a[i,n+1]:=a[i,n+1]-a[i,j]*p[j];
39       p[i]:=a[i,n+1]/a[i,i];
40     end;
41   end;
42 
43 procedure sort(l,r: longint);
44   var i,j: longint;
45       x:double;
46   begin
47     i:=l;
48     j:=r;
49     x:=c[(l+r) shr 1];
50     repeat
51       while c[i]<x do inc(i);
52       while x<c[j] do dec(j);
53       if not(i>j) then
54       begin
55         swap(c[i],c[j]);
56         inc(i);
57         j:=j-1;
58       end;
59     until i>j;
60     if l<j then sort(l,j);
61     if i<r then sort(i,r);
62   end;
63 
64 begin
65   readln(n,m);
66   for i:=1 to m do
67   begin
68     readln(x[i],y[i]);
69     inc(d[x[i]]);
70     inc(d[y[i]]);
71     w[x[i],d[x[i]]]:=y[i];
72     w[y[i],d[y[i]]]:=x[i];
73   end;
74   a[1,1]:=-1;
75   for i:=1 to d[1] do
76   begin
77     k:=w[1,i];
78     a[1,k]:=1/d[k];
79   end;
80   a[1,n+1]:=-1;
81   for i:=2 to n-1 do
82   begin
83     for j:=1 to d[i] do
84     begin
85       k:=w[i,j];
86       a[i,k]:=1/d[k];
87     end;
88     a[i,i]:=-1;
89   end;
90   a[n,n]:=1;
91   calc;
92   for i:=1 to m do
93     c[i]:=p[x[i]]/d[x[i]]+p[y[i]]/d[y[i]];
94   sort(1,m);
95   for i:=1 to m do
96     ans:=ans+c[i]*(m-i+1);
97   writeln(ans:0:3);
98 end.
View Code
原文地址:https://www.cnblogs.com/phile/p/4473050.html