bzoj 2878 [Noi2012]迷失游乐园——树上的期望dp
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2878
很好的树上概率题的思路,就是分成up和down。
代码中有众多小细节。让我弃疗好几天的致命小细节是dfs1里面那个sum要定义成double的!……
#include<iostream>
#include<cstdio>
#include<cstring>
#define db double
using namespace std;
const int N=1e5+;
int n,m,head[N],xnt,f[N],son[N],stack[N],top;
db down[N],up[N];
bool vis[N],in[N],flag;
struct Edge{
int next,to,w;
Edge(int n=,int t=,int w=):next(n),to(t),w(w) {}
}edge[N<<];
void add(int x,int y,int z)
{
edge[++xnt]=Edge(head[x],y,z);head[x]=xnt;
edge[++xnt]=Edge(head[y],x,z);head[y]=xnt;
}
void dfs1(int cr,int fa)
{
double sum=;//double
for(int i=head[cr],v;i;i=edge[i].next)
if((v=edge[i].to)!=fa&&!in[v])
{
son[cr]++;dfs1(v,cr);
sum+=down[v]+edge[i].w;//+edge[i].w!!
}
if(son[cr])down[cr]=sum/son[cr];
}
void dfs2(int cr,int fa,int d)
{
if(fa)//判断if(fa)!!
{
f[cr]=;//环上的点fa是0
up[cr]=d; //////如果放在下面的式子里,就少加了d ——但是怎么会有!(son[fa]-1+f[fa])的情况呢? //fa只有一条边的时候!
if(son[fa]-+f[fa])up[cr]+=(down[fa]*son[fa]-d-down[cr]+up[fa]*f[fa])/(son[fa]-+f[fa]);
// printf("cr=%d up=%.5lf(upfa=%.5lf)\n",cr,up[cr],up[fa]);
} //环上的点不求up,已在solve2里求过
for(int i=head[cr],v;i;i=edge[i].next)
if((v=edge[i].to)!=fa&&!in[v])dfs2(v,cr,edge[i].w);
}
void tarjan(int cr,int fa)
{
stack[++top]=cr;vis[cr]=;
for(int i=head[cr],v;i;i=edge[i].next)
if((v=edge[i].to)!=fa)
{
if(vis[v])
{
while(stack[top]!=v)in[stack[top--]]=;//!=v不是!=cr
in[stack[top--]]=;flag=;return;
}
else tarjan(v,cr);
if(flag)return;
}
top--;/////////
}
void solve(int root,int cr,int fa,double g,int d)/////自己的写法,判cr!=root!!
{
for(int i=head[cr],v;i;i=edge[i].next)
if(in[v=edge[i].to]&&v!=fa)
{
if(v==root)
{
up[root]+=g*(down[cr]+d);//
// printf("root=%d cr=%d up=%.5lf(down[cr]=%.5lf g=%.5lf)\n",root,cr,up[root],down[cr],g);
return;
}
if(cr!=root)up[root]+=g*(down[cr]+d)*son[cr]/(son[cr]+);//先+d再乘son[cr]
// printf("root=%d cr=%d up=%.5lf(down[cr]=%.5lf son[cr]=%d g=%.5lf)\n",root,cr,up[root],down[cr],son[cr],g);
if(cr==root)solve(root,v,cr,g/,d+edge[i].w); //son可能有多个
else solve(root,v,cr,g/(son[cr]+),d+edge[i].w);
}
}
int main()
{
scanf("%d%d",&n,&m);int x,y,z;
if(n==)
{
printf("0.00000");return ;
}
for(int i=;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);add(x,y,z);
}
if(m==n-)dfs1(,),dfs2(,,);
else{
tarjan(,);
for(int i=;i<=n;i++)if(in[i])dfs1(i,);
for(int i=;i<=n;i++)if(in[i])solve(i,i,,,);///!!!!!!!!
for(int i=;i<=n;i++)if(in[i])f[i]=,dfs2(i,,);
}
// for(int i=1;i<=n;i++)printf("i=%d up=%.5lf down=%.5lf\n",i,up[i],down[i]);
double sum=;
for(int i=;i<=n;i++)sum+=(down[i]*son[i]+up[i]*f[i])/(son[i]+f[i]);
printf("%.5lf",sum/n);
return ;
}
bzoj 2878 [Noi2012]迷失游乐园——树上的期望dp的更多相关文章
- BZOJ 2878: [Noi2012]迷失游乐园( 树形dp )
一棵树的话直接树形dp(求出往下走和往上走的期望长度). 假如是环套树, 环上的每棵树自己做一遍树形dp, 然后暴力枚举(环上的点<=20)环上每个点跑经过环上的路径就OK了. -------- ...
- bzoj 2878: [Noi2012]迷失游乐园【树上期望dp+基环树】
参考:https://blog.csdn.net/shiyukun1998/article/details/44684947 先看对于树的情况 设d[u]为点u向儿子走的期望长度和,du[u]为u点的 ...
- bzoj 2878: [Noi2012]迷失游乐园
#include<iostream> #include<cstring> #include<cstdio> #define M 100005 #define ld ...
- 【BZOJ 2878】 2878: [Noi2012]迷失游乐园 (环套树、树形概率DP)
2878: [Noi2012]迷失游乐园 Description 放假了,小Z觉得呆在家里特别无聊,于是决定一个人去游乐园玩.进入游乐园后,小Z看了看游乐园的地图,发现可以将游乐园抽象成有n个景点.m ...
- 2878: [Noi2012]迷失游乐园 - BZOJ
Description 放假了,小Z觉得呆在家里特别无聊,于是决定一个人去游乐园玩.进入游乐园后,小Z看了看游乐园的地图,发现可以将游乐园抽象成有n个景点.m条道路的无向连通图,且该图中至多有一个环( ...
- BZOJ 2878([Noi2012]-失落的游乐园树DP+出站年轮加+后市展望DP+vector的erase)
2878: [Noi2012]迷失乐园 Time Limit: 10 Sec Memory Limit: 512 MBSec Special Judge Submit: 319 Solved: ...
- [bzoj2878][Noi2012]迷失游乐园(基环树dp)
[bzoj2878][Noi2012]迷失游乐园(基环树dp) bzoj luogu 题意:一颗数或是基环树,随机从某个点开始一直走,不走已经到过的点,求无路可走时的路径长期望. 对于一棵树: 用两个 ...
- 【BZOJ】4872: [Shoi2017]分手是祝愿 期望DP
[题意]给定n盏灯的01状态,操作第 i 盏灯会将所有编号为 i 的约数的灯取反.每次随机操作一盏灯直至当前状态能够在k步内全灭为止(然后直接灭),求期望步数.n,k<=10^5. [算法]期望 ...
- bzoj 1415: [Noi2005]聪聪和可可 期望dp+记忆化搜索
期望dp水题~ 你发现每一次肯定是贪心走 2 步,(只走一步的话就可能出现环) 然后令 $f[i][j]$ 表示聪在 $i$,可在 $j$,且聪先手两个人碰上面的期望最小次数. 用记忆化搜索转移就行了 ...
随机推荐
- 重装window 7系统,从做一个u盘启动盘,到装系统,很不错
老毛桃U盘启动盘制作工具是现在最流行的U盘装系统和维护电脑的专用工具,一是制作简单,几乎100%支持所有U盘一键制作为启动盘,不必顾虑以前量产U盘考虑专用工具的问题.二是制作后工具功能强大,支持GHO ...
- IT行业的一些专业术语
SDK:SDK(Software Development Kit, 即软件开发工具包 )一般是一些被软件工程师用于为特定的软件包.软件框架.硬件平台.操作系统等建立应用软件的开发工具的集合. 参考:h ...
- Boot 横向布局
<div class="form-group"> <label for="name" class="col-lg-2 control ...
- Treflection03_getFields_getField
1. package reflectionZ; import java.lang.reflect.Constructor; import java.lang.reflect.Field; public ...
- 用TestPMD测试DPDK性能和功能
本文介绍了数据平面开发工具包(DPDK)TestPMD应用程序,展示了如何构建和配置TestPMD, 以及如何用它来检查使用DPDK的不同网络设备的性能和功能. TestPMD是一个使用DPDK软件包 ...
- FM算法 的总结
FM的总结: 1.FM算法与线性回归相比增加了特征的交叉.自动选择了所有特征的两两组合,并且给出了两两组合的权重. 2.上一条所说的,如果给两两特征的组合都给一个权重的话,需要训练的参数太多了.比如我 ...
- Java多线程编程总结
Java线程:概念与原理 Java线程:创建与启动 Java线程:线程栈模型与线程的变量 Java线程:线程状态的转换 Java线程:线程的同步与锁 Java线程:线程的交互 Java线程:线程的调 ...
- wget 官方jdk
每次下载jdk都是一件头疼的事,特别是在服务器上下载. 之前想的是下载到本地,然后通过ftp工具传上去.汗.. 后来想到用wget 直接下载到服务器上. 在网上找了几个例子,wget 加参数,如:wg ...
- tflearn kears GAN官方demo代码——本质上GAN是先训练判别模型让你能够识别噪声,然后生成模型基于噪声生成数据,目标是让判别模型出错。GAN的过程就是训练这个生成模型参数!!!
GAN:通过 将 样本 特征 化 以后, 告诉 模型 哪些 样本 是 黑 哪些 是 白, 模型 通过 训练 后, 理解 了 黑白 样本 的 区别, 再输入 测试 样本 时, 模型 就可以 根据 以往 ...
- Android 中的BroadCastReceiver
BroadCastReceiver 简介 (末尾有源码) BroadCastReceiver 源码位于: framework/base/core/java/android.content.Broadc ...