• 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
  • 相关阅读:
    Mac使用Homebrew进行软件包管理
    RNN模拟二进制加法
    虚拟机安装ubuntu18.04
    github合并分支到master
    Python配置虚拟环境
    Python的进程、线程、协程
    原码,反码,补码
    MySQL中的截位函数:RIGHT与LEFT
    MySQL查询和删除重复记录
    Mysql中的数据类型
  • 原文地址:https://www.cnblogs.com/phile/p/4473050.html
Copyright © 2020-2023  润新知