bzoj2878 [Noi2012]迷失游乐园——概率期望DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2878
这个博客写得很好:https://www.cnblogs.com/qt666/p/7252284.html
其实就是分成子树部分(down)和向上的部分(up)来考虑、转移;
要想清楚vis的作用等等,还有那个ed的使用,是和fa配套的,也就是只在子树中使用;
期望就是其他状态的期望和除以总状态数,只要想清楚有些什么状态就很好转移了!
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int const maxn=3e5+;
int n,m,fa[maxn],f[maxn],son[maxn],head[maxn],ct,ed[maxn],cir[maxn],cnt,dfn[maxn],tim,b[maxn];
double down[maxn],up[maxn],ans;
bool vis[maxn];
struct N{
int to,next,w;
N(int t=,int n=,int w=):to(t),next(n),w(w) {}
}edge[maxn];
void add(int x,int y,int z)
{
edge[++ct]=N(y,head[x],z);head[x]=ct;
edge[++ct]=N(x,head[y],z);head[y]=ct;
}
void dfs_down(int x)
{
vis[x]=;int tot=;
for(int i=head[x],v;i;i=edge[i].next)
{
if(vis[v=edge[i].to])continue;
ed[v]=edge[i].w;//
dfs_down(v);tot++;
down[x]+=down[v]+edge[i].w;
}
if(tot)down[x]/=tot;//
son[x]=tot;vis[x]=;//
}
void dfs_up(int x,int u)
{
// fa[x]=u;f[x]=1;
// if(u&&son[u])up[x]+=(up[u]+down[u]*son[u]-down[x]-ed[x])/son[u]+ed[x];
// for(int i=head[x],v;i;i=edge[i].next)
// if(!f[v=edge[i].to])ed[v]=edge[i].w,dfs_up(v,x);
vis[x]=;if(u) f[x]=;
if((son[u]-+f[u])&&u) up[x]+=(up[u]*f[u]+son[u]*down[u]-down[x]-ed[x])/(son[u]-+f[u]);//特判根节点(只有一个son的)
for(int i=head[x],v;i;i=edge[i].next)
if(!vis[v=edge[i].to]) /*ed[i]=edge[i].w,*/
up[v]+=edge[i].w,dfs_up(v,x);//在down时已求出ed
}
void make(int rt,int x)
{
for(int i=x;i!=fa[rt];i=fa[i])//不是i!=rt !!!
cir[++cnt]=i,b[cnt+]=ed[i],f[i]=,vis[i]=;//vis在dfs_down中会用
//犯蠢把 cir[++cnt]=i 写成 cir[++cnt]=x ,调了半天!!!
}
void tarjan(int x,int ff)
{
dfn[x]=++tim;fa[x]=ff;
for(int i=head[x],v;i;i=edge[i].next)
{
if(!dfn[v=edge[i].to])ed[v]=edge[i].w,tarjan(v,x);
else if(dfn[v]>dfn[x])b[]=edge[i].w,make(x,v);
}
}
void solve(int x,int j,int step)
{
double g=0.5,d=;
for(int i=;i<cnt;i++)//所求的都是up[x]!
{
if(step==-)d+=b[j];j+=step;//是b而不是ed
if(j==)j=cnt;if(j==cnt+)j=;
if(step==)d+=b[j];//j+后再+b[j],顺、逆时针有所区分
if(i==cnt-)up[x]+=g*(d+down[cir[j]]);
else up[x]+=g*(d+down[cir[j]])*son[cir[j]]/(son[cir[j]]+);
g/=son[cir[j]]+;
}
}
void work()//!
{
tarjan(,);
for(int i=;i<=cnt;i++)dfs_down(cir[i]),vis[cir[i]]=;//
for(int i=;i<=cnt;i++)solve(cir[i],i,),solve(cir[i],i,-);
for(int i=;i<=cnt;i++)dfs_up(cir[i],);//由于vis,只处理子树
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=,x,y,z;i<=m;i++)
scanf("%d%d%d",&x,&y,&z),add(x,y,z);
if(m==n-)dfs_down(),dfs_up(,);
else work();
for(int i=;i<=n;i++)
ans+=(down[i]*son[i]+up[i]*f[i])/(son[i]+f[i]);
printf("%.5lf",ans/n);//ans/n!
return ;
}
bzoj2878 [Noi2012]迷失游乐园——概率期望DP的更多相关文章
- [bzoj2878][Noi2012]迷失游乐园(基环树dp)
[bzoj2878][Noi2012]迷失游乐园(基环树dp) bzoj luogu 题意:一颗数或是基环树,随机从某个点开始一直走,不走已经到过的点,求无路可走时的路径长期望. 对于一棵树: 用两个 ...
- BZOJ2878 NOI2012迷失游乐园(树形dp+环套树+概率期望)
考虑树的部分分怎么做.令f[i]为i向子树内走的期望路径长度,转移比较显然.算答案时先把其父亲的答案弄好就可以统计自己的答案了. 环套树也类似.树里直接dp,对环上点暴力考虑环上的每条路径,算完后再在 ...
- [BZOJ2878][NOI2012]迷失游乐园(环套树DP+概率)
推荐讲解:https://www.cnblogs.com/Tunix/p/4561493.html 首先考虑树的情况,就是经典的树上概率DP.先DP出down表示从这个点向儿子走能走的期望长度,再DP ...
- [luogu2081 NOI2012] 迷失游乐园 (树形期望dp 基环树)
传送门 题目描述 放假了,小Z觉得呆在家里特别无聊,于是决定一个人去游乐园玩. 进入游乐园后,小Z看了看游乐园的地图,发现可以将游乐园抽象成有n个景点.m条道路的无向连通图,且该图中至多有一个环(即m ...
- BZOJ2878 [Noi2012]迷失游乐园 【基环树 + 树形dp + 期望dp】
题目链接 BZOJ2878 题解 除了实现起来比较长,思维难度还是挺小的 观察数据范围发现环长不超过\(20\),而我们去掉环上任何一个点就可以形成森林 于是乎我们枚举断掉的点,然后只需求出剩余每个点 ...
- bzoj2878 [Noi2012]迷失游乐园 [树形dp]
Description 放假了,小Z认为呆在家里特别无聊.于是决定一个人去游乐园玩. 进入游乐园后.小Z看了看游乐园的地图,发现能够将游乐园抽象成有n个景点.m条道路的无向连通图,且该图中至多有一个环 ...
- BZOJ2878 [Noi2012]迷失游乐园
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- 【BZOJ 2878】 2878: [Noi2012]迷失游乐园 (环套树、树形概率DP)
2878: [Noi2012]迷失游乐园 Description 放假了,小Z觉得呆在家里特别无聊,于是决定一个人去游乐园玩.进入游乐园后,小Z看了看游乐园的地图,发现可以将游乐园抽象成有n个景点.m ...
- BZOJ 2878: [Noi2012]迷失游乐园( 树形dp )
一棵树的话直接树形dp(求出往下走和往上走的期望长度). 假如是环套树, 环上的每棵树自己做一遍树形dp, 然后暴力枚举(环上的点<=20)环上每个点跑经过环上的路径就OK了. -------- ...
随机推荐
- 浅谈云网融合与SD-WAN
一.引言 近年来,SD-WAN作为一项新技术在行业应用领域里快速发展,企业对SD-WAN的接受度日渐提升,各厂商也纷纷提出解决方案.随着全球云计算领域的活跃创新和我国云计算发展进入应用普及阶段,越来越 ...
- js -- 监听窗口的大小变化
- 在canvas上面拖拽对象。
原文:https://html5.litten.com/how-to-drag-and-drop-on-an-html5-canvas/ 下面作者的原始的版本会抖动一下(鼠标刚点下去的时候,位置会发生 ...
- win7下 安装 source code pro
转: http://my.oschina.net/yearnfar/blog/325107 source code pro 字体安装, 一. 去 https://github.com/adobe-fo ...
- cocos2d-x-3.6 引擎概述
cocos2d-x是一个游戏开发引擎,从公布到如今也有五六年了,一路看它慢慢壮大.它是如今应用最多的开源2d引擎,没有之中的一个,据说已经占据90%的市场,所以.对于想从事游戏开发的童鞋来说还是有必要 ...
- memcached优化方法
工作原理 基本概念:slab,page.chunk. slab,是一个逻辑概念. 它是在启动memcached实例的时候预处理好的,每一个slab相应一个chunk size.也就是说 ...
- hdu5289(2015多校1)--Assignment(单调队列)
Assignment Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total ...
- spring test---測试SpringMvc初识
如今越来越多人使用SpringMvc来开发系统,在开发中可定须要对后台url地址请求測试,而且返回预期的结果! Spring提供的測试类MockMvc来进行url地址请求測试,使用方方式: packa ...
- UnsatisfiedLinkError: No implementation found for , AndroidStudio使用*.so
今天工作的时候.发现了一个jni的问题,java.lang.UnsatisfiedLinkError: No implementation found for...... 问题1:后来查了资料后发现. ...
- Sharepoint2013 列表的NewForm 页面加入一个 保存新建 button
昨天一同事问我怎样在sharepoint2013的NewForm.aspx页面上加入一个 save and new的button.实现save 和new的功能.save的功能和默认的save按钮效果一 ...