考虑树的部分分怎么做。令f[i]为i向子树内走的期望路径长度,转移比较显然。算答案时先把其父亲的答案弄好就可以统计自己的答案了。

  环套树也类似。树里直接dp,对环上点暴力考虑环上的每条路径,算完后再在树里统计答案。

  说起来不是很难。事实上想清楚了也确实不是很难。

  不明白为什么不管啥题我都能把代码写的贼长。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
#define N 100010
int n,m,p[N],degree[N],nxtlen[N],t=-;
int dfn[N],low[N],top=,cnt=,tot=,circle[N];
bool flag[N<<],iscircle[N<<];
double f[N],g[N],ans=;
struct data{int to,nxt,len;
}edge[N<<];
void addedge(int x,int y,int z){t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].len=z,p[x]=t;}
void dfs(int k,int from)
{
for (int i=p[k];~i;i=edge[i].nxt)
if (edge[i].to!=from&&!iscircle[edge[i].to])
{
dfs(edge[i].to,k);
degree[k]++;
f[k]+=f[edge[i].to]+edge[i].len;
}
if (degree[k]) f[k]/=degree[k];
}
void getans(int k,int from)
{
for (int i=p[k];~i;i=edge[i].nxt)
if (edge[i].to!=from)
{
g[edge[i].to]=(f[edge[i].to]*degree[edge[i].to]+edge[i].len+(g[k]*(degree[k]+(k>))-f[edge[i].to]-edge[i].len)/(degree[k]-(k==)))/(degree[edge[i].to]+);
getans(edge[i].to,k);
}
}
void getans2(int k,int from)
{
for (int i=p[k];~i;i=edge[i].nxt)
if (edge[i].to!=from&&!iscircle[edge[i].to])
{
g[edge[i].to]=(f[edge[i].to]*degree[edge[i].to]+edge[i].len+(g[k]*(degree[k]++(k==from))-f[edge[i].to]-edge[i].len)/(degree[k]+(k==from)))/(degree[edge[i].to]+);
getans2(edge[i].to,k);
}
}
void tarjan(int k,int from)
{
dfn[k]=low[k]=++cnt;
for (int i=p[k];~i;i=edge[i].nxt)
if (edge[i].to!=from)
{
if (!dfn[edge[i].to]) tarjan(edge[i].to,k),low[k]=min(low[k],low[edge[i].to]);
else low[k]=min(low[k],dfn[edge[i].to]);
if (low[edge[i].to]>dfn[k]) flag[i]=flag[i^]=;
}
}
void findcircle(int k)
{
circle[++tot]=k;iscircle[k]=;
for (int i=p[k];~i;i=edge[i].nxt)
if (!iscircle[edge[i].to]&&!flag[i]) findcircle(edge[i].to);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj2878.in","r",stdin);
freopen("bzoj2878.out","w",stdout);
#endif
n=read(),m=read();
memset(p,,sizeof(p));
for (int i=;i<=m;i++)
{
int x=read(),y=read(),z=read();
addedge(x,y,z),addedge(y,x,z);
}
if (m==n-)
{
dfs(,);
g[]=f[];
if (degree[]>) getans(,);
else g[edge[p[]].to]=(f[edge[p[]].to]*degree[edge[p[]].to]+edge[p[]].len)/(degree[edge[p[]].to]+),getans(edge[p[]].to,);
for (int i=;i<=n;i++) ans+=g[i];
}
else
{
for (int i=;i<=n;i++) if (!dfn[i]) tarjan(i,i);
for (int i=;i<=n;i++)
{
for (int j=p[i];~j;j=edge[j].nxt)
if (!flag[j]) {findcircle(i);break;}
if (tot) break;
}
for (int i=;i<=tot;i++)
for (int j=p[circle[i]];~j;j=edge[j].nxt)
if (edge[j].to==circle[i%tot+]) nxtlen[i]=edge[j].len;
for (int i=;i<=tot;i++) dfs(circle[i],circle[i]);
for (int i=;i<=tot;i++)
{
double P=;
int x=i%tot+,sum=nxtlen[i];
while (x!=i)
{
if (degree[circle[x]])
{
g[circle[i]]+=P*degree[circle[x]]/(degree[circle[x]]+(x%tot+!=i))*(f[circle[x]]+sum);
P/=(degree[circle[x]]+);
}
else if (x%tot+==i) g[circle[i]]+=P*sum;
sum+=nxtlen[x];
x=x%tot+;
}
}
for (int i=;i<=tot;i++)
{
double P=;
int x=i>?i-:tot,sum=nxtlen[x];
while (x!=i)
{
if (degree[circle[x]])
{
g[circle[i]]+=P*degree[circle[x]]/(degree[circle[x]]+((x>?x-:tot)!=i))*(f[circle[x]]+sum);
P/=(degree[circle[x]]+);
}
else if ((x>?x-:tot)==i) g[circle[i]]+=P*sum;
x=x>?x-:tot;
sum+=nxtlen[x];
}
g[circle[i]]+=f[circle[i]]*degree[circle[i]];
g[circle[i]]/=degree[circle[i]]+;
getans2(circle[i],circle[i]);
}
for (int i=;i<=n;i++) ans+=g[i];
}
printf("%.5lf",ans/n);
return ;
}

BZOJ2878 NOI2012迷失游乐园(树形dp+环套树+概率期望)的更多相关文章

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

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

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

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

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

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

  4. 【BZOJ-1040】骑士 树形DP + 环套树 + DFS

    1040: [ZJOI2008]骑士 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3312  Solved: 1269[Submit][Status ...

  5. [BZOJ2878][NOI2012]迷失游乐园(环套树DP+概率)

    推荐讲解:https://www.cnblogs.com/Tunix/p/4561493.html 首先考虑树的情况,就是经典的树上概率DP.先DP出down表示从这个点向儿子走能走的期望长度,再DP ...

  6. BZOJ 1040 树形DP+环套树

    就是有n个点n条边,那么有且只有一个环那么用Dfs把在环上的两个点找到.然后拆开,从这条个点分别作树形Dp即可. #include <cstdio> #include <cstrin ...

  7. BZOJ2878 [Noi2012]迷失游乐园 【基环树 + 树形dp + 期望dp】

    题目链接 BZOJ2878 题解 除了实现起来比较长,思维难度还是挺小的 观察数据范围发现环长不超过\(20\),而我们去掉环上任何一个点就可以形成森林 于是乎我们枚举断掉的点,然后只需求出剩余每个点 ...

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

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

  9. bzoj2878 [Noi2012]迷失游乐园——概率期望DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2878 这个博客写得很好:https://www.cnblogs.com/qt666/p/72 ...

随机推荐

  1. monkey测试入门1

    Monkey是一款通过命令行来对我们APP进行测试的工具,可以运行在模拟器里或真机上.它向系统发送伪随机的用户事件流,实现对正应用程序进行压力测试. 官方介绍 :https://developer.a ...

  2. VM虚拟机安装CentOS 7.0添加jdk环境

    虚拟机注册码 5A02H-AU243-TZJ49-GTC7K-3C61N 安装centos系统,网络类型选择桥接网络安装完成后vi /etc/sysconfig/network-scripts/ifc ...

  3. [硬件配置]记录Ubuntu 14.04 下安装无线网卡驱动解决无法连接WiFi的过程

    新电脑安装了Ubuntu 14.04,但是网络连接中只有以太网而没有WiFi的选项. 打开System Setting系统设置-Software&Updates软件&更新-Additi ...

  4. NO--14 微信小程序,左右联动二

    上一篇讲解了左=>右联动,那个还比较简单,本篇写剩下比较核心的部分,也是本次开发过程中遇到最难的部分,右=>左联动,先简单看一下演示   右左联动.gif 一.关键技术: (1) 小程序 ...

  5. CentOS查看一共安装了多少软件包,是那些软件包

    转载请注明出处:http://blog.csdn.net/l1028386804/article/details/48292853 一.如何得知共安装了多少个软件包 [root@localhost ~ ...

  6. 绝对干货!初学者也能看懂的DPDK解析

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由Willko发表于云+社区专栏 一.网络IO的处境和趋势 从我们用户的使用就可以感受到网速一直在提升,而网络技术的发展也从1GE/10 ...

  7. join命令详解

    基础命令学习目录首页 原文链接:https://www.cnblogs.com/agilework/archive/2012/04/18/2454877.html 功能说明:将两个文件中,指定栏位内容 ...

  8. 【转】Java生成plist下载ipa文件

    我们在上传ipa想要安装的时候必须要通过plist文件去下载,并且还要遵循 itms-services协议. 意思就是,第一步我们要生成一个plist文件, 第二步生成一个html文件,用来指向pli ...

  9. “Hello World!”Final发布文案加美工

    文案: 大家好,我们是“Hello World!”团队,本次我将向大家简要介绍一下空天猎的final发布,在空天猎final发布中,我主要从以下两个方面向大家进行介绍,第一个方面是增加了敌方的boss ...

  10. cnblogs用户体验评价

    1. 是否提供良好的体验给用户(同时提供价值)? 博客园就相当于现在生活中处处可见的微博,所有人都在上面发表自己的一些看法,当然我们比较关注的是计算机编程方面的一些博客,大多数编程人员愿意分享自己的代 ...