传送门

题意:给一棵nnn个点的带边权树或基环树,随机选一个点作为起点,每次随机走到一个相邻未走过的位置,直到无路可走。求期望路径长度。

n≤105n \leq 10^5n≤105,为基环树时环的大小不超过202020

先考虑树怎么做废话

先只考虑从根往下走

显然就是

fu=∑v∈son(u)w(u,v)+f(v)∣son(u)∣f_u={\sum_{v\in son(u)}w(u,v)+f(v) \over|son(u)|}fu​=∣son(u)∣∑v∈son(u)​w(u,v)+f(v)​

考虑其他位置

再考虑强制第一步往上走,然后强行不走回来的期望为ggg

方程见代码

对于基环树,fff不受影响。

对于环上的点两个方向带着走到这里的概率和距离转一圈,算出ggg,树上点方程不变。

然后就可以了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
#define MAXN 100005
#define MAXM 200005
using namespace std;
struct edge{int u,v,w;}e[MAXM];
int head[MAXN],nxt[MAXM],cnt;
inline int read()
{int ans=0;char c=getchar();while (!isdigit(c)) c=getchar();while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();return ans;
}
void addnode(int u,int v,int w)
{e[++cnt]=(edge){u,v,w};nxt[cnt]=head[u];head[u]=cnt;
}
int n,m,son[MAXN];
double F[MAXN],G[MAXN];
namespace Tree
{void dfs(int u,int f){for (int i=head[u];i;i=nxt[i])if (e[i].v!=f){++son[u];dfs(e[i].v,u);F[u]+=F[e[i].v]+e[i].w;}if (son[u]) F[u]/=son[u];}void DFS(int v,int f){int u=e[f].u;G[v]=e[f].w+((u==1&&son[u]==1)? 0:((G[u]+F[u]*son[u]-F[v]-e[f].w)/(son[u]-(u==1))));for (int i=head[v];i;i=nxt[i])if (e[i].v!=u)DFS(e[i].v,i);}void solve(){dfs(1,0);for (int i=head[1];i;i=nxt[i]) DFS(e[i].v,i);double ans=F[1];for (int i=2;i<=n;i++) ans+=G[i]/(son[i]+1)+F[i]*son[i]/(son[i]+1);printf("%.5f",ans/n);}
}
namespace Circle
{bool vis[MAXN],isrt[MAXN];int rt[MAXN],w[MAXN],tot,tmp;void findroot(int u,int f){vis[u]=true;for (int i=head[u];i;i=nxt[i])if (!vis[e[i].v]&&e[i].v!=rt[1]){findroot(e[i].v,u);if (isrt[e[i].v]&&e[i].v!=tmp) isrt[rt[++tot]=u]=true,w[tot]=e[i].w;}elseif (e[i].v!=f&&e[i].v!=rt[1])isrt[rt[tot=1]=u]=true,w[1]=e[i].w,tmp=e[i].v;vis[u]=false;}void DFS(int v,int f){int u=e[f].u;if (isrt[u]) G[v]=e[f].w+2.0/(son[u]+1)*G[u]+(F[u]*son[u]-F[v]-e[f].w)/(son[u]+1);else G[v]=e[f].w+(G[u]+F[u]*son[u]-F[v]-e[f].w)/son[u];for (int i=head[v];i;i=nxt[i])if (e[i].v!=u)DFS(e[i].v,i);}void solve(){findroot(1,0);for (int t=1;t<=tot;t++){int u=rt[t];for (int i=head[u];i;i=nxt[i])if (!isrt[e[i].v])++son[u],Tree::dfs(e[i].v,u),F[u]+=F[e[i].v]+e[i].w;if (son[u]) F[u]/=son[u];}for (int i=1;i<=tot;i++){double p=0.5;int dis=0;for (int j=i%tot+1;j!=i;j=j%tot+1){dis+=w[j];if (j%tot+1==i) G[rt[i]]+=p*(dis+F[rt[j]]);else G[rt[i]]+=p*son[rt[j]]/(son[rt[j]]+1)*(dis+F[rt[j]]);p*=1.0/(son[rt[j]]+1);}p=0.5,dis=w[i];for (int j=(i==1? tot:i-1);j!=i;j=(j==1? tot:j-1)){if (i%tot+1==j) G[rt[i]]+=p*(dis+F[rt[j]]);else  G[rt[i]]+=p*son[rt[j]]/(son[rt[j]]+1)*(dis+F[rt[j]]);p*=1.0/(son[rt[j]]+1);dis+=w[j];}}for (int t=1;t<=tot;t++){int u=rt[t];for (int i=head[u];i;i=nxt[i])if (!isrt[e[i].v])DFS(e[i].v,i);}double ans=0;for (int i=1;i<=n;i++) ans+=(isrt[i]+1)*G[i]/(son[i]+isrt[i]+1)+F[i]*son[i]/(son[i]+isrt[i]+1);printf("%.5f",ans/n);     }
}
int main()
{n=read(),m=read();for (int i=1;i<=m;i++){int u,v,w;u=read(),v=read(),w=read();addnode(u,v,w);addnode(v,u,w);}if (m==n-1) Tree::solve();else Circle::solve();return 0;
}

【NOI2012】迷失游乐园【概率期望】【换根dp】【基环树】相关推荐

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

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

  2. 换根dp求树所有节点的最小深度

    链接:https://ac.nowcoder.com/acm/contest/18072/A 牛妹有一张连通图,由n个点和n-1条边构成,也就是说这是一棵树,牛妹可以任意选择一个点为根,根的深度为0, ...

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

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

  4. 树形dp ---- 树形换根dp F - The Maximum Subtree

    题目链接 题目大意: 给定一颗树,求这个树的最大子树,且这个子树是一个good-tree. good-tree的定义是:每个节点可以表示成一个数值区间,而树上的边表示两个点表示的数值区间相交 解题思路 ...

  5. 2020牛客多校第一场B虚树+质数筛+换根dp

    题目大意: 1.可以发现阶乘增长是很快的所以你要把整颗树建立出来是不实际的. 2.我们可以假设这棵树已经建出来出来了我们应该怎么搞 首先很明显是一个树形dp, 我们设dp[j],是以j为u到其他点距离 ...

  6. BZOJ 2159 「国家集训队」Crash 的文明世界(第二类斯特林数,换根DP)【BZOJ计划】

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 题目链接 https://hydro.ac/d/bzoj/p/2159 是 hydro 的 BZOJ ...

  7. UOJ #214 合唱队形 (概率期望计数、DP、Min-Max容斥)

    UOJ #214 合唱队形 (概率期望计数.DP.Min-Max容斥) 9个月的心头大恨终于切掉了!!!! 非常好的一道题,不知为何uoj上被点了70个差评. 题目链接: http://uoj.ac/ ...

  8. 洛谷 - P4323 [JSOI2016]独特的树叶(树上哈希+换根dp)

    题目链接:点击查看 题目大意:给出一棵 n 个节点的树 A ,再给出一棵 n + 1 个节点的树 B,题目保证了树 B 是树 A 添加了一个叶子结点后的一棵树,只不过编号的顺序不同,现在问这个叶子节点 ...

  9. 牛客多校1 - Infinite Tree(虚树+换根dp+树状数组)

    题目链接:点击查看 题目大意:给出一个无穷个节点的树,对于每个大于 1 的点 i 来说,可以向点 i / minvid[ i ] 连边,这里的 mindiv[ x ] 表示的是 x 的最小质因数,现在 ...

  10. [BZOJ4379][POI2015]Modernizacja autostrady[树的直径+换根dp]

    题意 给定一棵 \(n\) 个节点的树,可以断掉一条边再连接任意两个点,询问新构成的树的直径的最小和最大值. \(n\leq 5\times 10^5\) . 分析 记断掉一条边之后两棵树的直径为 \ ...

最新文章

  1. IDC:企业向云转变推动了SD-WAN市场增长
  2. Android实训日志:基于外部存储的音乐播放器V06
  3. 带你认识“货真价实”的P2P网贷风控
  4. 【python 6】Numpy
  5. 精度,精确率,召回率_了解并记住精度和召回率
  6. 简而言之,JUnit:测试结构
  7. 通过编程解决问题的正确思路
  8. 她发明了可以“喝的饭”,估值已超过10亿美金!从此每天多睡半小时....
  9. 开源软件公司易犯的 5 大错误,又该如何避免?
  10. 值得收藏的数据库基础总结!
  11. 随想录(找工作20问)
  12. 'yasm' 不是内部或外部命令
  13. java中的时间片概念_java中常用的时间处理类TimeUtil
  14. 推荐9个web前端模板框架
  15. Adapter(适配器)模式
  16. 高精度室内外融合定位服务平台-“羲和”系统
  17. 增持风行网 百视通在下一盘很大的棋
  18. 仓库5s管理推行难点分析
  19. 【数据库】数据、数据库、数据库管理系统、数据库系统
  20. 如何在java面试中给出一个出彩的自我介绍

热门文章

  1. 知乎高赞:看懂这个颠覆世界观的认知,远比做1000道题更有用!
  2. 此内容过于真实,引起强烈舒适
  3. “爱因斯坦兄弟”事件轰动纽约时报!双胞胎乱写博士论文,整容后越黑越红,竟然名利双收..........
  4. 还在为孩子学不好数学而犯愁?你想要知道的或许在这!
  5. mysql 批量_mysql LOAD语句批量录入数据
  6. 实现图片打乱_疫情过后,是否打乱了你前进的脚步?面对现状,你将如何开展新的征程?...
  7. 访问Web服务器时 使用的协议是,使用SOAP协议访问Web服务
  8. 2020项目商机_2020未来商机,一万元可以做什么项目
  9. php 输出json utf8,php json_encode utf-8中文问题
  10. c语言 if 多个判断条件执行顺序_C语言之流程控制选择语句