• BZOJ 2878 迷失游乐园


    http://www.lydsy.com/JudgeOnline/problem.php?id=2878

    题意:n个点的图,保证图联通,有n-1或者n条边,求从任意一个点出发,不经过相同点,最终无路可走的路径长度期望。

    思路:m=n-1时,可以用dp,处理出i点往下,i点往上走的路径长度期望,然后O(n)统计就可以了。

    m=n时,由于环上点点数不超过20,那这就是基环树,我们考虑枚举基环树上面的点i,假设我们到了i,并走向了i的子树。

    这样我们就把环断开了,然后我们再两遍顺逆走这个环,就可以处理出up数组了,然后再分别下传到每个子树里。

      1 #include<algorithm>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<cstring>
      5 #include<iostream>
      6 int flag,n,m,f[200005],len[200005],vis[200005],tot,go[200005],next[200005],cnt,cir[200005],huan[200005],first[200005],val[200005],du[200005];
      7 double down[200005],up[200005];
      8 int read(){
      9     char ch=getchar();int t=0,f=1;
     10     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
     11     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
     12     return t*f;
     13 }
     14 void insert(int x,int y,int z){
     15     tot++;
     16     go[tot]=y;
     17     next[tot]=first[x];
     18     first[x]=tot;
     19     val[tot]=z;
     20 }
     21 void add(int x,int y,int z){
     22     insert(x,y,z);insert(y,x,z);
     23 }
     24 void dfs1(int x,int fa){
     25     vis[x]=1;
     26     for (int i=first[x];i;i=next[i]){
     27         int pur=go[i];
     28         if (vis[pur]) continue;
     29         dfs1(pur,x);
     30         down[x]+=(double)val[i]+(((double)down[pur])/((double)(du[pur]-1+(du[pur]==1))));
     31     }
     32 }
     33 void dfs2(int x,int fa){
     34     if (!cir[x]&&fa!=0) up[x]=len[x]+((double)((double)up[fa]+down[fa]-len[x]-((double)down[x])/((double)du[x]-1+(du[x]==1))))/((double)(du[fa]-1+(du[fa]==1)));
     35     vis[x]=1;
     36     for (int i=first[x];i;i=next[i]){
     37         int pur=go[i];
     38         if (vis[pur]) continue;
     39         f[pur]=x;
     40         len[pur]=val[i];
     41         dfs2(pur,x);
     42     }
     43 }
     44 void work1(){
     45     dfs1(1,0);
     46     for (int i=1;i<=n;i++) vis[i]=0;
     47     dfs2(1,0);
     48     double ans=0;
     49     for (int i=1;i<=n;i++) ans+=((double)down[i]+(double)up[i])/((double)du[i]);
     50     ans/=((double)(n));
     51     printf("%.5f
    ",ans);
     52 }
     53 void dfs(int x,int fa){
     54     vis[x]=1;
     55     for (int i=first[x];i;i=next[i]){
     56         int pur=go[i];
     57         if (flag) return;
     58         if (f[x]!=pur&&vis[pur]){
     59             len[pur]=val[i];
     60             int j=x;
     61             while (j!=f[pur]){
     62                 cnt++;
     63                 cir[j]=1;
     64                 huan[cnt]=j;
     65                 j=f[j];
     66             }
     67             flag=1;
     68             return;
     69         }else if (!vis[pur]){
     70             len[pur]=val[i];
     71             f[pur]=x;
     72             dfs(pur,x);
     73         }
     74     }
     75 }
     76 void work2(){
     77      flag=0;
     78      dfs(1,0);cnt++;    
     79      for (int i=1;i<=n;i++) vis[i]=0;
     80      for (int i=0;i<cnt;i++) vis[huan[i]]=1;
     81      for (int i=0;i<cnt;i++) dfs1(huan[i],0);
     82      for (int i=0;i<cnt;i++){
     83             int x=(i+1)%cnt;double s=1;
     84             while (x!=i){
     85                 if ((x+1)%cnt==i) up[huan[i]]+=(double)s*len[huan[(x-1+cnt)%cnt]]+((double)(s*down[huan[x]]))/((double)(du[huan[x]]-2+(du[huan[x]]==2)));
     86                 else up[huan[i]]+=(double)s*len[huan[(x-1+cnt)%cnt]]+((double)(s*down[huan[x]]))/((double)(du[huan[x]]-1));
     87                 s=s/((double)(du[huan[x]]-1));
     88                 x=(x+1)%cnt;
     89             }
     90             x=(i-1+cnt)%cnt;s=1;
     91             while (x!=i){
     92                 if ((x-1+cnt)%cnt==i) up[huan[i]]+=(double)s*len[huan[x]]+((double)(s*down[huan[x]]))/((double)(du[huan[x]]-2+(du[huan[x]]==2)));
     93                 else up[huan[i]]+=(double)s*len[huan[(x)%cnt]]+((double)(s*down[huan[x]]))/((double)(du[huan[x]]-1));
     94                 s=s/((double)(du[huan[x]]-1));
     95                 x=(x-1+cnt)%cnt;
     96             }
     97     }
     98     for (int i=1;i<=n;i++) vis[i]=0;
     99     for (int i=0;i<cnt;i++) vis[huan[i]]=1;
    100     for (int i=0;i<cnt;i++) dfs2(huan[i],0);
    101     double ans=0;
    102     for (int i=1;i<=n;i++) ans+=(down[i]+up[i])/(du[i]);
    103     printf("%.5f
    ",ans/n);
    104 }
    105 int main(){
    106     cnt=-1;
    107     n=read();m=read();flag=0;
    108     for (int i=1;i<=m;i++){
    109         int x=read(),y=read(),z=read();
    110         add(x,y,z);
    111         du[x]++;du[y]++;
    112     }
    113     if (m==n-1) work1();
    114     else work2();
    115 }
  • 相关阅读:
    写爬虫,怎么可以不会正则呢?
    从 Scrapy 学习模块导入技巧
    博客已搬家至CSDN
    更改JDK默认编码,解决DBeaver乱码问题
    【2020面试】- Java中常见集合的默认大小以及扩容机制
    【2020面试】- CAS机制与自旋锁
    【2020面试】- filter和interceptor的区别
    【20k中级开发】-面试题201117
    【开发笔记】
    RPC 调用和 HTTP 调用的区别
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5600846.html
Copyright © 2020-2023  润新知