zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    出售几个闲置的玉米
    竞价账户时好时坏怎样分析找到原因?
    两行代码轻松搞定网页自动刷新,简单,实用。
    BCompare文件对比神器 工程师 开发必备工具之一
    关于 Apache 屏蔽 IP 地址
    一段 JavaScript 实现禁止用户打开控制台与鼠标右键查看源码
    Apache使用.htaccess防盗链禁止用户下载
    HTML5下video右键禁用-禁止右键下载视频
    python装饰器
    部署nginx支持lua
  • 原文地址:https://www.cnblogs.com/phile/p/4610980.html
Copyright © 2011-2022 走看看