[bzoj2878][Noi2012]迷失游乐园(基环树dp)
[bzoj2878][Noi2012]迷失游乐园(基环树dp)
题意:一颗数或是基环树,随机从某个点开始一直走,不走已经到过的点,求无路可走时的路径长期望。
对于一棵树:
用两个$dp$数组分别记录从这个点起向上向下走的期望
向下走的$dp$不用多说
向上走的$dp$:
对于从$u$计算$v$的dp
$dp[v]$应当是从u向周围引出所有路径减去走向t的路径的期望后再除以$deg_{u}-1$
对于基环树:
环上的点很少。
此时环上的点的向上$dp$指从u出发向环上两头走的期望。
如何计算:对于环上每一个点都向环的两头各dp一次取平均值。
完毕。
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=100011;
const double eps=1e-8;
template<typename TP>void read(TP &kk){
#define ak *
TP phy=0,ioi=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')ioi=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){phy=phy*10+ch-'0';ch=getchar();}
kk=phy ak ioi;
}
int n,m;
struct sumireko
{
int to,ne,w;
}e[N*2];
int he[N],ecnt;
void addline(int f,int t,int w)
{
e[++ecnt].to=t;
e[ecnt].ne=he[f];
he[f]=ecnt;
e[ecnt].w=w;
}
bool onr[N];
double deg[N],sc[N],dpu[N],dpd[N];
void dfs1(int x,int f)
{
for(int i=he[x],t;i;i=e[i].ne)
{
t=e[i].to;
if(t==f||onr[t]) continue;
dfs1(t,x);
dpd[x]+=dpd[t]+e[i].w;
}
if(sc[x]>eps) dpd[x]/=sc[x];
}
void dfs2(int x,int f)
{
for(int i=he[x],t;i;i=e[i].ne)
{
t=e[i].to;
if(f==t||onr[t]) continue;
dpu[t]=e[i].w;
if(deg[x]-1.0>eps)dpu[t]+=(dpd[x]*sc[x]-e[i].w-dpd[t]+dpu[x]*(deg[x]-sc[x]))/(deg[x]-1.0);
dfs2(t,x);
}
}
int rnd[N],hp;
int sp;bool vv[N];
int find(int x,int f)
{
if(vv[x]){sp=x;return 1;}
vv[x]=1;int tmp;
for(int i=he[x],t;i;i=e[i].ne)
{
t=e[i].to;
if(t==f) continue;
if(tmp=find(t,x))
{
if(tmp==1)
{
rnd[++hp]=x;
onr[x]=1;
if(x!=sp) return 1;
}
return 2;
}
}
return 0;
}
double dpt[N];
void dfs3(int x,int f,int o,int s)
{
if(!o)
{
int g=0;
for(int i=he[x],t;i;i=e[i].ne)
{
t=e[i].to;
if(!onr[t]) continue;
g++;dfs3(t,x,g,s);
dpu[x]+=dpt[t]+e[i].w;
}
dpu[x]/=2;
return;
}
double tmp=0;
dpt[x]=0;
for(int i=he[x],t;i;i=e[i].ne)
{
t=e[i].to;
if(!onr[t]||t==s||t==f) continue;
dfs3(t,x,o,s);
dpt[x]+=dpt[t]+e[i].w;
tmp+=1;
}
if(sc[x]+tmp>eps)
dpt[x]=(dpt[x]+dpd[x]*sc[x])/(sc[x]+tmp);
} double ans;
int xi,yi,wi;
int main()
{
read(n),read(m);
for(int i=1;i<=m;i++)
{
read(xi),read(yi),read(wi);
addline(xi,yi,wi),addline(yi,xi,wi),deg[xi]+=1,deg[yi]+=1;
}
if(m==n-1)
{
for(int i=1;i<=n;i++) sc[i]=deg[i]-1;
sc[1]+=1;
dfs1(1,0);
dfs2(1,0);
for(int i=1;i<=n;i++) ans+=(dpd[i]*sc[i]+dpu[i])/deg[i];
ans/=n;
printf("%.5lf\n",ans);
return 0;
}
find(1,0);
for(int i=1;i<=n;i++) sc[i]=deg[i]-(onr[i]?2.0:1.0);
for(int i=1;i<=hp;i++) dfs1(rnd[i],0);
for(int i=1;i<=hp;i++) dfs3(rnd[i],0,0,rnd[i]);
for(int i=1;i<=hp;i++) dfs2(rnd[i],0);
for(int i=1;i<=n;i++) ans+=(dpd[i]*sc[i]+dpu[i]*(deg[i]-sc[i]))/deg[i];
ans/=n;
printf("%.5lf\n",ans);
return 0;
}
[bzoj2878][Noi2012]迷失游乐园(基环树dp)的更多相关文章
- [BZOJ2878][NOI2012]迷失游乐园(环套树DP+概率)
推荐讲解:https://www.cnblogs.com/Tunix/p/4561493.html 首先考虑树的情况,就是经典的树上概率DP.先DP出down表示从这个点向儿子走能走的期望长度,再DP ...
- BZOJ2878 NOI2012迷失游乐园(树形dp+环套树+概率期望)
考虑树的部分分怎么做.令f[i]为i向子树内走的期望路径长度,转移比较显然.算答案时先把其父亲的答案弄好就可以统计自己的答案了. 环套树也类似.树里直接dp,对环上点暴力考虑环上的每条路径,算完后再在 ...
- bzoj2878 [Noi2012]迷失游乐园——概率期望DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2878 这个博客写得很好:https://www.cnblogs.com/qt666/p/72 ...
- BZOJ2878 [Noi2012]迷失游乐园 【基环树 + 树形dp + 期望dp】
题目链接 BZOJ2878 题解 除了实现起来比较长,思维难度还是挺小的 观察数据范围发现环长不超过\(20\),而我们去掉环上任何一个点就可以形成森林 于是乎我们枚举断掉的点,然后只需求出剩余每个点 ...
- [luogu2081 NOI2012] 迷失游乐园 (树形期望dp 基环树)
传送门 题目描述 放假了,小Z觉得呆在家里特别无聊,于是决定一个人去游乐园玩. 进入游乐园后,小Z看了看游乐园的地图,发现可以将游乐园抽象成有n个景点.m条道路的无向连通图,且该图中至多有一个环(即m ...
- 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了. -------- ...
随机推荐
- Solution -「CF 1622F」Quadratic Set
\(\mathscr{Description}\) Link. 求 \(S\subseteq\{1,2,\dots,n\}\),使得 \(\prod_{i\in S}i\) 是完全平方数,并最 ...
- Centos下Ambari2.7.5的编译和安装
前言 终于,要开始写点大数据相关的文章了.当真的要开始写老本行的时候,还是考虑了挺久的.一是不知道从何处写起,二是如何能写点有意思的. 我们常说,过程比结果重要.也是有很多人喜欢准备完全之后,才会开始 ...
- 【数据共享】基于Landsat提取的全球河网(河宽)GDWL数据库
GRWL数据库,全称Global River Widths from Landsat Database,是由Allen, George H & Pavelsky. Tamlin M等人基于La ...
- Acme-https证书申请
Linux下使用acme.sh 配置https 免费证书 简单来说acme.sh 实现了 acme 协议, 可以从 let's encrypt 生成免费的证书. acme.sh 有以下特点: 一个纯粹 ...
- 『无为则无心』Python面向对象 — 58、类方法和静态方法
目录 1.实例方法 2.类方法 (1)类方法特点 (2)类方法使用场景 3.静态方法 (1)静态方法特点 (2)静态方法使用场景 1.实例方法 实例方法既可以调用静态方法也可以调用类方法. # 定义一 ...
- 【01】Maven依赖插件之maven-dependency-plugin
一.插件目标(goal) 1.analyze:分析项目依赖,确定哪些是已使用已声明的,哪些是已使用未声明的,哪些是未使用已声明的 2.analyze-dep-mgt:分析项目依赖,列出已解析的依赖项与 ...
- SpringMVC教程--eclipse中使用maven创建springMVC项目
一.在eclipse中创建maven-archetype-webapp项目: 1.新建项目选择maven项目 2.默认,下一步 3.选择maven-archetype-webapp,其他保持默认即可 ...
- 昇思MindSpore全场景AI框架 1.6版本,更高的开发效率,更好地服务开发者
摘要:本文带大家快速浏览昇思MindSpore全场景AI框架1.6版本的关键特性. 全新的昇思MindSpore全场景AI框架1.6版本已发布,此版本中昇思MindSpore全场景AI框架易用性不断改 ...
- SAPD:FSAF升级版,合理的损失值加权以及金字塔特征选择 | ECCV 2020
针对anchor-point检测算法的优化问题,论文提出了SAPD方法,对不同位置的anchor point使用不同的损失权重,并且对不同的特征金字塔层进行加权共同训练,去除了大部分人为制定的规则,更 ...
- 微信小程序如何测试?
不需要安装,只要在微信里找到这个小程序打开即可使用,由于小程序的便捷,如今越来越多的平台开发方都纷纷推出自身的小程序应用. 那我们该如何进行微信小程序测试呢? 1.功能测试 功能测试以需求文档和交互视 ...