终于补完NOI2012了好开心~

题目大意:给定一棵树或者环套外向树,求出从中随机选一条简单路径的期望长度,环上点数不超过20。

d[x]表示x的度数,ch[x]表示x孩子个数

up[x]表示x向上走的期望长度,down[x]表示x向下走的期望长度

f[x]表示x的父亲

树的情况:

环套外向树的情况:

先找出环,对于每棵树用之前的方法求出down[]

对环上每个点i顺时针逆时针各走一圈,求出up[i]:

up[i]=sum((i走到j的概率)*(way(i,j)+down[j])*(j往它孩子走的概率))

i走到j的概率分两种情况讨论,

以顺时针为例,

第一步由于要确定是顺时针还是逆时针,所以顺时针走概率为0.5,

之后每一步概率/=(上一个点孩子数+1)

j往它孩子走的概率分两种情况讨论,

以顺时针为例,

每一步向下走概率为该点孩子数/(该点孩子数+1),最后一步由于不可能回到i点,所以向下走概率为1

然后用树的方法求出其它点的up[]

再统计ans即可

没加任何优化居然跑了Rank1…

#include<cstdio>
#define N 100010
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
int n,m,i,j,x,y,z;
int g[N],nxt[N<<1],w[N<<1],v[N<<1],ed,pre[N],ch[N],d[N],fw[N],st,sum;
int cnt,a[N<<1],s[N<<1];
double up[N],down[N],ans,p;
bool vis[N],in[N];
inline void add(int x,int y,int z){d[x]++;v[++ed]=y;w[ed]=z;nxt[ed]=g[x];g[x]=ed;}
void dfs1(int x,int f){
for(int i=g[x];i;i=nxt[i])if(v[i]!=f&&!in[v[i]])dfs1(v[i],x),ch[x]++,down[x]+=down[v[i]]+w[i];
if(ch[x])down[x]/=ch[x];
}
void dfs2(int x,int f){
for(int i=g[x];i;i=nxt[i])if(v[i]!=f&&!in[v[i]]){
up[v[i]]=w[i];
if(d[x]>1)up[v[i]]+=(up[x]*(d[x]-ch[x])+down[x]*ch[x]-w[i]-down[v[i]])/(d[x]-1);
dfs2(v[i],x);
}
}
void find(int x,int f,int l){
if(st)return;
pre[x]=f;fw[x]=l;
if(vis[x]){st=f;return;}
vis[x]=1;
for(int i=g[x];i;i=nxt[i])if(v[i]!=f)find(v[i],x,w[i]);
}
int main(){
for(read(n),read(m);i<m;i++)read(x),read(y),read(z),add(x,y,z),add(y,x,z);
if(m<n)dfs1(1,0),dfs2(1,0);else{
find(1,0,0);
for(in[a[cnt=1]=st]=1,i=pre[st];i!=st;i=pre[i])in[a[++cnt]=i]=1;
for(i=1;i<=cnt;i++)a[i+cnt]=a[i],s[i+1]=s[i+cnt+1]=fw[a[i]];
for(i=1;i<=cnt;i++)dfs1(a[i],0);
for(i=1;i<=cnt;i++){
//i->j
j=i+1;p=0.5;sum=s[j];
up[a[i]]+=p*(sum+down[a[j]])*ch[a[j]]/(ch[a[j]]+1);
p/=ch[a[j]]+1;
for(j=i+2;j<i+cnt-1;j++){
sum+=s[j];
up[a[i]]+=p*(sum+down[a[j]])*ch[a[j]]/(ch[a[j]]+1);
p/=ch[a[j]]+1;
}
j=i+cnt-1;
sum+=s[j];
up[a[i]]+=p*(sum+down[a[j]]);
//j<-i
j=i+cnt-1;p=0.5;sum=s[j+1];
up[a[i]]+=p*(sum+down[a[j]])*ch[a[j]]/(ch[a[j]]+1);
p/=ch[a[j]]+1;
for(j=i+cnt-2;j>i+1;j--){
sum+=s[j+1];
up[a[i]]+=p*(sum+down[a[j]])*ch[a[j]]/(ch[a[j]]+1);
p/=ch[a[j]]+1;
}
j=i+1;
sum+=s[j+1];
up[a[i]]+=p*(sum+down[a[j]]);
}
for(i=1;i<=cnt;i++)dfs2(a[i],0);
}
for(i=1;i<=n;i++)ans+=(down[i]*ch[i]+up[i]*(d[i]-ch[i]))/d[i];
printf("%.5f",ans/n);
return 0;
}

  

NOI2012 : 迷失游乐园的更多相关文章

  1. BZOJ 2878: [Noi2012]迷失游乐园( 树形dp )

    一棵树的话直接树形dp(求出往下走和往上走的期望长度). 假如是环套树, 环上的每棵树自己做一遍树形dp, 然后暴力枚举(环上的点<=20)环上每个点跑经过环上的路径就OK了. -------- ...

  2. 【BZOJ 2878】 2878: [Noi2012]迷失游乐园 (环套树、树形概率DP)

    2878: [Noi2012]迷失游乐园 Description 放假了,小Z觉得呆在家里特别无聊,于是决定一个人去游乐园玩.进入游乐园后,小Z看了看游乐园的地图,发现可以将游乐园抽象成有n个景点.m ...

  3. [bzoj2878][Noi2012]迷失游乐园(基环树dp)

    [bzoj2878][Noi2012]迷失游乐园(基环树dp) bzoj luogu 题意:一颗数或是基环树,随机从某个点开始一直走,不走已经到过的点,求无路可走时的路径长期望. 对于一棵树: 用两个 ...

  4. 2878: [Noi2012]迷失游乐园 - BZOJ

    Description 放假了,小Z觉得呆在家里特别无聊,于是决定一个人去游乐园玩.进入游乐园后,小Z看了看游乐园的地图,发现可以将游乐园抽象成有n个景点.m条道路的无向连通图,且该图中至多有一个环( ...

  5. 【BZOJ 2878】 [Noi2012]迷失游乐园

    Description 放假了,小Z觉得呆在家里特别无聊,于是决定一个人去游乐园玩.进入游乐园后,小Z看了看游乐园的地图,发现可以将游乐园抽象成有n个景点.m条道路的无向连通图,且该图中至多有一个环( ...

  6. BZOJ2878 [Noi2012]迷失游乐园

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  7. bzoj2878 [Noi2012]迷失游乐园 [树形dp]

    Description 放假了,小Z认为呆在家里特别无聊.于是决定一个人去游乐园玩. 进入游乐园后.小Z看了看游乐园的地图,发现能够将游乐园抽象成有n个景点.m条道路的无向连通图,且该图中至多有一个环 ...

  8. [luogu2081 NOI2012] 迷失游乐园 (树形期望dp 基环树)

    传送门 题目描述 放假了,小Z觉得呆在家里特别无聊,于是决定一个人去游乐园玩. 进入游乐园后,小Z看了看游乐园的地图,发现可以将游乐园抽象成有n个景点.m条道路的无向连通图,且该图中至多有一个环(即m ...

  9. bzoj 2878: [Noi2012]迷失游乐园

    #include<iostream> #include<cstring> #include<cstdio> #define M 100005 #define ld ...

随机推荐

  1. xocde真机测试 内存查看

    如上, 有的时候真机调试, 内存和cpu占用没有被展示出来, 那么真机测试的时候怎么查看我们当前使用的内存呢, 有办法: instrument->activity monitory 点击左上角的 ...

  2. Coursera台大机器学习技法课程笔记04-Soft-Margin Support Vector Machine

    之前的SVM非常的hard,要求每个点都要被正确的划分,这就有可能overfit,为此引入了Soft SVM,即允许存在被错分的点,将犯的错放在目 标函数中进行优化,非常类似于正则化. 将Soft S ...

  3. nginx(五)nginx与php的安装配置

    经过前面学习,对nginx有个大概的了解,来配置LNMP;只要是在系统安装过程中选择安装比较齐全的包,基本上系统都能满足安装要求,下面是我一个一个测试的,基本上全部安装所需的库文件,放心安装: [ro ...

  4. nyoj 8

    http://acm.nyist.net/JudgeOnline/problem.php?pid=8 #include<stdio.h> #include<iostream> ...

  5. Linux下PS1、PS2、PS3、PS4使用详解

    参考印象笔记:

  6. 如何利用phpize在生产环境中为php添加新的扩展php-bcmath

    在日常的开发当中,随着开发的功能越来越复杂.对运行环境的要求也就随着需求的变化需要不断地更新和变化.一个在线的生产系统不可能一开始就满足了所有的运行依赖,因此动态地添加依赖就显得比较必要了.如果你的应 ...

  7. 字母排列_next_permutation_字典序函数_待解决

    问题 B: 字母排列 时间限制: 1 Sec  内存限制: 64 MB提交: 19  解决: 5[提交][状态][讨论版] 题目描述 当给出一串字符时,我们逐个可以变换其字符,形成新的字符串.假如对这 ...

  8. 【读书笔记】读《JavaScript设计模式》之装饰者模式

    一.定义 装饰者模式可用来透明地把对象包装在具有同样接口的另一个对象之中.这样一来,你可以给一个方法添加一些行为,然后将方法调用传递给原始对象.相对于创建子类来说,使用装饰者对象是一种更灵活的选择(装 ...

  9. js “+” 连接字符串&数字相加 数字相加出现多位小数 函数调用单引号双引号嵌套和转义字符的使用

    一.机制 JavaScript中,加号不仅表示相加还表示字符串连接 当加号两边存在字符串时,加号代表连接,实际上是将两侧都转为了字符串,如 "1" + 1 = "11&q ...

  10. Git入门学习和应用笔记

    >>关于Git 1.BitMover公司收回Linux社区的BitKeeper免费使用权,Linus花了两周时间自己用C写了一个分布式版本控制系统,这就是Git.2.什么是集中式版本控制系 ...