• bzoj2878


    又是环套树dp,这次不是我擅长的类型

    首先考虑树上的暴力,肯定是穷举起点然后以起点为根dp

    我们用g[i]表示以点i为期望走的路径总长,答案就是1/n*Σ(g[i]/d[i]) (d[i]表示点度数)

    不难发现我们只需要两次dfs就能求出g[i],即先求出向下的,然后求向上的

    具体的,我们设f[x]表示x向孩子走期望路径长度,这个一次dfs就可以求出来,这时候g[x]求出来的是向孩子走期望路径的总长

    再做一次dfs,要加上向上走的路径,可以得到g[y]=g[y]+(g[x]-f[y]-w(x,y))/(d[x]-1)+w(x,y) [fa[y]=x] 注意度数为1的点

    那么树就搞定了,环怎么做呢?

    还是按照基本思路,把环放到根上,求出环上每个点向下的g[x]

    注意到题目给出的条件,环上的点很少,因此我们可以暴力依次计算每个点的g[x]

    还是类似上面的思路,并不难,注意细节即可

      1 type node=record
      2        po,next,num:longint;
      3      end;
      4 
      5 var w,u,f,g:array[0..100010] of double;
      6     cir,v:array[0..100010] of boolean;
      7     fp,fa,d,p,b,q,c:array[0..100010] of longint;
      8     e:array[0..200010] of node;
      9     j,i,n,m,len,x,y,z,s,t:longint;
     10     ans:double;
     11 
     12 procedure add(x,y,z:longint);
     13   begin
     14     inc(len);
     15     e[len].po:=y;
     16     e[len].next:=p[x];
     17     e[len].num:=z;
     18     p[x]:=len;
     19     inc(d[x]);
     20   end;
     21 
     22 procedure dfs1(x:longint);
     23   var i,y:longint;
     24   begin
     25     v[x]:=true;
     26     i:=p[x];
     27     while i<>0 do
     28     begin
     29       y:=e[i].po;
     30       if not v[y] and not cir[y] then
     31       begin
     32         dfs1(y);
     33         g[x]:=g[x]+f[y]+e[i].num;
     34       end;
     35       i:=e[i].next;
     36     end;
     37     if d[x]>1 then f[x]:=g[x]/(d[x]-1);
     38   end;
     39 
     40 procedure dfs2(x:longint);
     41   var i,y,k:longint;
     42   begin
     43     v[x]:=true;
     44     i:=p[x];
     45     while i<>0 do
     46     begin
     47       y:=e[i].po;
     48       if not v[y] and not cir[y] then
     49       begin
     50         k:=d[x]-1;
     51         if k=0 then k:=1;
     52         g[y]:=g[y]+(g[x]-f[y]-e[i].num)/k+e[i].num;
     53         dfs2(y);
     54       end;
     55       i:=e[i].next;
     56     end;
     57   end;
     58 
     59 procedure find(x:longint);
     60   var i,y,z:longint;
     61   begin
     62     inc(t);
     63     b[x]:=t;
     64     i:=p[x];
     65     while i<>0 do
     66     begin
     67       y:=e[i].po;
     68       if b[y]=0 then
     69       begin
     70         fa[y]:=x;
     71         fp[y]:=e[i].num;
     72         find(y);
     73       end
     74       else if (y<>fa[x]) and (b[y]<b[x]) then
     75       begin
     76         cir[y]:=true;
     77         z:=x;
     78         inc(s); q[1]:=y;
     79         c[1]:=e[i].num;
     80         while z<>y do
     81         begin
     82           inc(s);
     83           q[s]:=z;
     84           c[s]:=fp[z];
     85           cir[z]:=true;
     86           z:=fa[z];
     87         end;
     88       end;
     89       i:=e[i].next;
     90     end;
     91   end;
     92 
     93 begin
     94   readln(n,m);
     95   for i:=1 to m do
     96   begin
     97     readln(x,y,z);
     98     add(x,y,z);
     99     add(y,x,z);
    100   end;
    101   if m=n-1 then
    102   begin
    103     dfs1(1);
    104     fillchar(v,sizeof(v),false);
    105     dfs2(1);
    106   end
    107   else begin
    108     find(1);
    109     fillchar(v,sizeof(v),false);
    110     for i:=1 to s do
    111     begin
    112       x:=q[i];
    113       d[x]:=d[x]-2;
    114       dfs1(x);
    115       q[i+s]:=q[i];
    116       c[i+s]:=c[i];
    117     end;
    118     for i:=1 to s do
    119     begin
    120       for j:=i+s-1 downto i do
    121       begin
    122         x:=q[j];
    123         if j=i+s-1 then
    124         begin
    125           z:=d[x];
    126           if z=0 then inc(z);
    127           u[x]:=g[x]/z;
    128         end
    129         else begin
    130           u[x]:=u[q[j+1]]+c[j];
    131           if j<>i then
    132             u[x]:=(u[x]+g[x])/(d[x]+1);
    133         end;
    134       end;
    135       for j:=i+1 to i+s do
    136       begin
    137         x:=q[j];
    138         if j<>i+s then u[x]:=0;
    139         if j=i+1 then
    140         begin
    141           z:=d[x];
    142           if z=0 then inc(z);
    143           u[x]:=g[x]/z;
    144         end
    145         else begin
    146           u[x]:=u[x]+u[q[j-1]]+c[j-1];
    147           if j<>i+s then
    148             u[x]:=(u[x]+g[x])/(d[x]+1);
    149         end;
    150       end;
    151       w[q[i]]:=u[q[i]];
    152     end;
    153     fillchar(v,sizeof(v),false);
    154     for i:=1 to s do
    155     begin
    156       x:=q[i];
    157       g[x]:=g[x]+w[x];
    158       d[x]:=d[x]+2;
    159     end;
    160     for i:=1 to s do
    161       dfs2(q[i]);
    162   end;
    163   for i:=1 to n do
    164     ans:=ans+g[i]/d[i];
    165   writeln(ans/n:0:5);
    166 end.
    View Code
  • 相关阅读:
    数据劫持
    OpenGL渲染流程
    MySQL查询数据库所有表名及其注释
    java json转义问题(消除反斜杠 etc)
    ubuntu 安装后黑屏问题。
    封装一个函数用来对比原始数组与更新后的数组增加和删除了那些数据
    从tree类型数据格式中找到自己想找到的数据(递归方式)
    elinput输入的几种限制
    封装一个列表转为Tree树结构的方法
    接上一篇使用递归获取Tree数据结构中的目标数据,封装了一个通用函数
  • 原文地址:https://www.cnblogs.com/phile/p/4610980.html
Copyright © 2020-2023  润新知