考虑树的部分分怎么做。令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. 【转】利用telnet来进行调试Skynet

    https://blog.csdn.net/WhereIsHeroFrom/article/details/80674408

  2. windows下在idea用maven导入spark2.3.1源码并编译并运行示例

    一.前提 1.配置好maven:intellij idea maven配置及maven项目创建 2.下载好spark源码: 二.导入源码: 1.将下载的源码包spark-2.3.1.tgz解压(E:\ ...

  3. JetBrains激活 PyCharm | IntelliJ IDEA | CLion | WebStorm...

    最近,JetBrains的IDE火了起来,身为学Java的人,放弃了Eclipse,选择了Idea,还真有点不舍得呢... 虽然Idea不错(在我看来,比Eclipse好用),但是,人家是收费的呀.. ...

  4. 高可用OpenStack(Queen版)集群-13.分布式存储Ceph

    参考文档: Install-guide:https://docs.openstack.org/install-guide/ OpenStack High Availability Guide:http ...

  5. rev命令详解

    基础命令学习目录首页 rev命令将文件中的每行内容以字符为单位反序输出,即第一个字符最后输出,最后一个字符最先输出,依次类推. #cat a.txt wo shi mcw, nihao how do ...

  6. jobs命令详解

    基础命令学习目录首页 在用管理员执行一个命令后,用Ctrl+Z把命令转移到了后台.导致无法退出root的. 输入命令:exit终端显示:There are stopped jobs. 解决方法:方法一 ...

  7. 常用函数-filter、map、reduce、sorted

    常用函数 filter map reduce sorted和列表自带sort 待续... 一.filter函数 1.说明 filter()函数接收一个函数 f 和一个可迭代对象,这个函数 f 的作用是 ...

  8. jenkins设置定时任务

    每次都手动的构建项目显然不够方便,有时候需要定时地执行自动化测试脚本.例如,每天晚上定时执行 pjenkins.py 文件来运行自动化测试项目. 设置定时任务 前面已经创建的 “python test ...

  9. 20135316王剑桥 linux第六周课实验笔记

    6.存储器层次结构 6.1存储技术 1.如果你的程序需要的数据是存储在CPU寄存器中的,那么在执行期间,在零个周期内就能访问到它们.如果存储在高速缓冲中,需要1-10个周期.如果存储在主存中,需要50 ...

  10. JAVA实验报告三:敏捷开发与XP实践

    实验内容 1. XP基础 2. XP核心实践 3. 相关工具 实验步骤 (一)敏捷开发与XP 软件工程是把系统的.有序的.可量化的方法应用到软件的开发.运营和维护上的过程.软件工程包括下列领域:软件需 ...