• 2878: [Noi2012]迷失游乐园


    Description

    放假了,小Z觉得呆在家里特别无聊,于是决定一个人去游乐园玩。进入游乐园后,小Z看了看游乐园的地图,发现可以将游乐园抽象成有n个景点、m条道路的无向连通图,且该图中至多有一个环(即m只可能等于n或者n-1)。小Z现在所在的大门也正好是一个景点。小Z不知道什么好玩,于是他决定,从当前位置出发,每次随机去一个和当前景点有道路相连的景点,并且同一个景点不去两次(包括起始景点)。贪玩的小Z会一直游玩,直到当前景点的相邻景点都已经访问过为止。小Z所有经过的景点按顺序构成一条非重复路径,他想知道这条路径的期望长度是多少?小Z把游乐园的抽象地图画下来带回了家,可是忘了标哪个点是大门,他只好假设每个景点都可能是大门(即每个景点作为起始点的概率是一样的)。同时,他每次在选择下一个景点时会等概率地随机选择一个还没去过的相邻景点。
    Input


    第一行是两个整数n和m,分别表示景点数和道路数。 接下来行,每行三个整数Xi, Yi, Wi,分别表示第i条路径的两个景点为Xi, Yi,路径长Wi。所有景点的编号从1至n,两个景点之间至多只有一条道路。
    Output

     共一行,包含一个实数,即路径的期望长度。
    Sample Input
    4 3
    1 2 3
    2 3 1
    3 4 4
    Sample Output
    6.00000000

    【样例解释】样例数据中共有6条不同的路径: 路径 长度 概率
    1-->4 8 1/4
    2-->1 3 1/8
    2-->4 5 1/8
    3-->1 4 1/8
    3-->4 4 1/8
    4-->1 8 1/4
    因此期望长度 = 8/4 + 3/8 + 5/8 + 4/8 + 4/8 + 8/4 = 6.00
    【评分方法】本题没有部分分,你程序的输出只有和标准答案的差距不超过0.01时,才能获得该测试点的满分,否则不得分。
    【数据规模和约定】对于100%的数据,1 <= Wi <= 100。 测试点编号 n m 备注
    1 n=10 m = n-1 保证图是链状
    2 n=100 只有节点1的度数大于2
    3 n=1000 /
    4 n=100000 /
    5 n=100000 /
    6 n=10 m = n /
    7 n=100 环中节点个数<=5
    8 n=1000 环中节点个数<=10
    9 n=100000 环中节点个数<=15
    10 n=100000 环中节点个数<=20

    一直WA,最后才发现环没仔细考虑,因为最后一个是不可能走到i的所以度数减1

    就是求一个down和一个up,分别表示向下走的期望长度和向上走的期望长度

    对于环,我们以每个环上的节点为根求一边down

    然后枚举环上的点更新up值,环上点的up值就表示第一条边走环边的期望长度

    然后用环上节点的up值更新其他点的up值

      1 const
      2     maxn=100100;
      3 var
      4     first,d,fa:array[0..maxn]of longint;
      5     up,down:array[0..maxn]of double;
      6     vis,cir:array[0..maxn]of boolean;
      7     last,next,w:array[0..maxn*2]of longint;
      8     huan,len:array[0..maxn]of longint;
      9     n,m,tot,cnt:longint;
     10     ans:double;
     11     flag:boolean;
     12  
     13 procedure insert(x,y,z:longint);
     14 begin
     15     inc(tot);
     16     last[tot]:=y;
     17     next[tot]:=first[x];
     18     first[x]:=tot;
     19     w[tot]:=z;
     20     inc(d[y]);
     21 end;
     22  
     23 procedure dfs(x:longint);
     24 var
     25     i,j:longint;
     26 begin
     27     vis[x]:=true;
     28     i:=first[x];
     29     while i<>0 do
     30         begin
     31             if flag then exit;
     32             if (vis[last[i]])and(fa[x]<>last[i]) then
     33             begin
     34                 len[last[i]]:=w[i];
     35                 j:=x;
     36                 while j<>fa[last[i]] do
     37                     begin
     38                         inc(cnt);cir[j]:=true;
     39                         huan[cnt]:=j;
     40                         j:=fa[j];
     41                     end;
     42                 flag:=true;exit;
     43             end;
     44             if not vis[last[i]] then
     45             begin
     46                 fa[last[i]]:=x;len[last[i]]:=w[i];
     47                 dfs(last[i]);
     48             end;
     49             i:=next[i];
     50         end;
     51 end;
     52  
     53 procedure dfs1(x:longint);
     54 var
     55     i:longint;
     56 begin
     57     vis[x]:=true;
     58     i:=first[x];
     59     while i<>0 do
     60         begin
     61             if not vis[last[i]] then
     62             begin
     63                 dfs1(last[i]);
     64                 down[x]:=down[x]+w[i]+down[last[i]]/(d[last[i]]-1+longint(d[last[i]]=1));
     65             end;
     66             i:=next[i];
     67         end;
     68 end;
     69  
     70 procedure dfs2(x:longint);
     71 var
     72     i:longint;
     73 begin
     74     if (not cir[x]) and (fa[x]<>0) then up[x]:=len[x]+(up[fa[x]]+down[fa[x]]-len[x]-down[x]/(d[x]-1+longint(d[x]=1)))/(d[fa[x]]-1+longint(d[fa[x]]=1));
     75     vis[x]:=true;
     76     i:=first[x];
     77     while i<>0 do
     78         begin
     79             if not vis[last[i]] then
     80             begin
     81                 fa[last[i]]:=x;len[last[i]]:=w[i];
     82                 dfs2(last[i]);
     83             end;
     84             i:=next[i];
     85         end;
     86 end;
     87  
     88 procedure main;
     89 var
     90     i,x,y,z:longint;
     91     s:double;
     92 begin
     93     read(n,m);cnt:=-1;
     94     for i:=1 to m do
     95         begin
     96             read(x,y,z);
     97             insert(x,y,z);
     98             insert(y,x,z);
     99         end;
    100     if m=n-1 then
    101         begin
    102             dfs1(1);
    103             for i:=1 to n do vis[i]:=false;
    104             dfs2(1);
    105             for i:=1 to n do ans:=ans+(up[i]+down[i])/d[i];
    106         end
    107     else
    108         begin
    109             dfs(1);
    110             for i:=1 to n do vis[i]:=false;
    111             for i:=0 to cnt do vis[huan[i]]:=true;
    112             for i:=0 to cnt do dfs1(huan[i]);
    113             for i:=0 to cnt do
    114                 begin
    115                     x:=(i+1)mod(cnt+1);s:=1;
    116                     while x<>i do
    117                         begin
    118                             if (x+1)mod(cnt+1)=i then up[huan[i]]:=up[huan[i]]+s*len[huan[(x+cnt)mod(cnt+1)]]+s*down[huan[x]]/(d[huan[x]]-2+longint(d[huan[x]]=2))
    119                             else up[huan[i]]:=up[huan[i]]+s*len[huan[(x+cnt)mod(cnt+1)]]+s*down[huan[x]]/(d[huan[x]]-1);
    120                             s:=s/(d[huan[x]]-1);
    121                             x:=(x+1)mod(cnt+1);
    122                         end;
    123                     x:=(i+cnt)mod(cnt+1);s:=1;
    124                     while x<>i do
    125                         begin
    126                             if (x+cnt)mod(cnt+1)=i then up[huan[i]]:=up[huan[i]]+s*len[huan[x]]+s*down[huan[x]]/(d[huan[x]]-2+longint(d[huan[x]]=2))
    127                             else up[huan[i]]:=up[huan[i]]+s*len[huan[x]]+s*down[huan[x]]/(d[huan[x]]-1);
    128                             s:=s/(d[huan[x]]-1);
    129                             x:=(x+cnt)mod(cnt+1);
    130                         end;
    131                 end;
    132             for i:=1 to n do vis[i]:=false;
    133             for i:=0 to cnt do vis[huan[i]]:=true;
    134             for i:=0 to cnt do dfs2(huan[i]);
    135             for i:=1 to n do ans:=ans+(up[i]+down[i])/d[i];
    136         end;
    137     writeln(ans/n:0:5);
    138 end;
    139  
    140 begin
    141     main;
    142 end.
    View Code
  • 相关阅读:
    前端性能优化成神之路--图片懒加载(lazyload image)
    前端性能优化成神之路-异步加载
    浮动布局详解
    布局:上下两个div高度固定,中间自适应
    盒子模型和弹性盒子模型的详解
    CSRF攻击详解
    使用Base64格式的图片制作ICON
    如何让父元素有透明度,但里面的子元素不透明
    父级元素以及子元素高度宽度未知如何实现水平垂直居中
    php file文件操作函数
  • 原文地址:https://www.cnblogs.com/Randolph87/p/3794198.html
Copyright © 2020-2023  润新知