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

---------------------------------------------------------------------------------------------

#include<cstdio>
#include<cstring>
#include<algorithm>
 
using namespace std;
 
const int maxn = 100009;
 
int N, M, C, Root, deg[maxn], L[maxn], R[maxn], Lw[maxn], Rw[maxn];
bool vis[maxn];
double Eu[maxn], Ed[maxn];
 
struct edge {
int t, w;
edge* n;
} E[maxn << 1], *pt = E, *H[maxn];
 
inline void AddEdge(int u, int v, int w) {
deg[pt->t = v]++, pt->w = w, pt->n = H[u], H[u] = pt++;
}
 
void DFS_D(int x) {
vis[x] = true;
Ed[x] = 0;
for(edge* e = H[x]; e; e = e->n) if(!vis[e->t]) {
DFS_D(e->t);
Ed[x] += Ed[e->t] + e->w;
}
if(x == Root) {
Ed[x] /= max(1, (deg[x] - (M < N ? 0 : 2)));
} else if(deg[x] > 1)
Ed[x] /= deg[x] - 1;
}
 
void DFS_U(int x) {
vis[x] = true;
for(edge* e = H[x]; e; e = e->n) if(!vis[e->t]) {
int d = deg[x];
if(x != Root) {
d--;
} else if(M == N)
d -= 2;
double t = (Ed[x] * d - Ed[e->t] - e->w);
if(x == Root) {
if(M < N)
Eu[e->t] = t / max(1, d - 1);
else
Eu[e->t] = (t + Eu[x] * 2) / (d + 1);
} else
Eu[e->t] = (t + Eu[x]) / d;
Eu[e->t] += e->w;
DFS_U(e->t);
}
}
 
void DFS_U(int x, int nxt[], int nxtw[], double &t, int len, double p = 0.5) {
if(nxt[x] != Root) {
t += (Ed[x] + len) * p * (deg[x] - 2) / (deg[x] - 1);
DFS_U(nxt[x], nxt, nxtw, t, len + nxtw[x], p / (deg[x] - 1));
} else
t += (Ed[x] + len) * p;
}
 
bool DFS_C(int x, edge* r = NULL) {
vis[x] = true;
for(edge* e = H[x]; e; e = e->n) if(e != r) {
L[e->t] = x;
R[x] = e->t;
Lw[e->t] = Rw[x] = e->w;
if(vis[e->t]) {
C = e->t;
return true;
}
if(DFS_C(e->t, E + ((e - E) ^ 1))) return true;
}
return false;
}
 
void Init() {
scanf("%d%d", &N, &M);
int u, v, w;
for(int i = 0; i < M; i++) {
scanf("%d%d%d", &u, &v, &w);
u--, v--;
AddEdge(u, v, w);
AddEdge(v, u, w);
}
}
 
void Work() {
double ans = 0;
if(M < N) {
memset(vis, 0, sizeof vis);
DFS_D(Root = 0);
memset(vis, 0, sizeof vis);
Eu[0] = 0;
DFS_U(Root = 0);
ans = Ed[0];
for(int i = 1; i < N; i++)
ans += (Ed[i] * (deg[i] - 1) + Eu[i]) / deg[i];
} else {
memset(vis, 0, sizeof vis);
DFS_C(0);
Root = C;
do {
memset(vis, 0, sizeof vis);
vis[L[Root]] = vis[R[Root]] = true;
DFS_D(Root);
} while((Root = L[Root]) != C);
Root = C;
do {
DFS_U(L[Root], L, Lw, Eu[Root], Lw[Root]);
DFS_U(R[Root], R, Rw, Eu[Root], Rw[Root]);
} while((Root = L[Root]) != C);
Root = C;
do {
memset(vis, 0, sizeof vis);
vis[L[Root]] = vis[R[Root]] = true;
DFS_U(Root);
} while((Root = L[Root]) != C);
memset(vis, 0, sizeof vis);
Root = C;
do {
ans += (Ed[Root] * (deg[Root] - 2) + Eu[Root] * 2) / deg[Root];
vis[Root] = true;
} while((Root = L[Root]) != C);
for(int i = 0; i < N; i++)
if(!vis[i]) ans += (Ed[i] * (deg[i] - 1) + Eu[i]) / deg[i];
}
printf("%.5lf\n", ans / N);
}
 
int main() {
Init();
Work();
return 0;
}

---------------------------------------------------------------------------------------------

2878: [Noi2012]迷失游乐园

Time Limit: 10 Sec  Memory Limit: 512 MB
Submit: 752  Solved: 443
[Submit][Status][Discuss]

Description

放假了,小Z觉得呆在家里特别无聊,于是决定一个人去游乐园玩。进入游乐园后,小Z看了看游乐园的地图,发现可以将游乐园抽象成有n个景点、m条道路的无向连通图,且该图中至多有一个环(即m只可能等于n或者n-1)。小Z现在所在的大门也正好是一个景点。小Z不知道什么好玩,于是他决定,从当前位置出发,每次随机去一个和当前景点有道路相连的景点,并且同一个景点不去两次(包括起始景点)。贪玩的小Z会一直游玩,直到当前景点的相邻景点都已经访问过为止。小Z所有经过的景点按顺序构成一条非重复路径,他想知道这条路径的期望长度是多少?小Z把游乐园的抽象地图画下来带回了家,可是忘了标哪个点是大门,他只好假设每个景点都可能是大门(即每个景点作为起始点的概率是一样的)。同时,他每次在选择下一个景点时会等概率地随机选择一个还没去过的相邻景点。

Input

第一行是两个整数n和m,分别表示景点数和道路数。 接下来行,每行三个整数Xi, Yi, Wi,分别表示第i条路径的两个景点为Xi, Yi,路径长Wi。所有景点的编号从1至n,两个景点之间至多只有一条道路。

Output

共一行,包含一个实数,即路径的期望长度,保留五位小数

Sample Input

4 3
1 2 3
2 3 1
3 4 4

Sample Output

6.00000

【样例解释】样例数据中共有6条不同的路径: 路径 长度 概率
1-->4 8 1/4
2-->1 3 1/8
2-->4 5 1/8
3-->1 4 1/8
3-->4 4 1/8
4-->1 8 1/4
因此期望长度 = 8/4 + 3/8 + 5/8 + 4/8 + 4/8 + 8/4 = 6.00
【评分方法】本题没有部分分,你程序的输出只有和标准答案的差距不超过0.01时,才能获得该测试点的满分,否则不得分。
【数据规模和约定】对于100%的数据,1 <= Wi <= 100。 测试点编号 n m 备注
1 n=10 m = n-1 保证图是链状
2 n=100 只有节点1的度数大于2
3 n=1000 /
4 n=100000 /
5 n=100000 /
6 n=10 m = n /
7 n=100 环中节点个数<=5
8 n=1000 环中节点个数<=10
9 n=100000 环中节点个数<=15
10 n=100000 环中节点个数<=20

HINT

Source

BZOJ 2878: [Noi2012]迷失游乐园( 树形dp )的更多相关文章

  1. bzoj 2878 [Noi2012]迷失游乐园——树上的期望dp

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2878 很好的树上概率题的思路,就是分成up和down. 代码中有众多小细节.让我弃疗好几天的 ...

  2. bzoj 2878: [Noi2012]迷失游乐园【树上期望dp+基环树】

    参考:https://blog.csdn.net/shiyukun1998/article/details/44684947 先看对于树的情况 设d[u]为点u向儿子走的期望长度和,du[u]为u点的 ...

  3. bzoj 2878: [Noi2012]迷失游乐园

    #include<iostream> #include<cstring> #include<cstdio> #define M 100005 #define ld ...

  4. bzoj2878 [Noi2012]迷失游乐园 [树形dp]

    Description 放假了,小Z认为呆在家里特别无聊.于是决定一个人去游乐园玩. 进入游乐园后.小Z看了看游乐园的地图,发现能够将游乐园抽象成有n个景点.m条道路的无向连通图,且该图中至多有一个环 ...

  5. 【BZOJ 2878】 2878: [Noi2012]迷失游乐园 (环套树、树形概率DP)

    2878: [Noi2012]迷失游乐园 Description 放假了,小Z觉得呆在家里特别无聊,于是决定一个人去游乐园玩.进入游乐园后,小Z看了看游乐园的地图,发现可以将游乐园抽象成有n个景点.m ...

  6. [luogu2081 NOI2012] 迷失游乐园 (树形期望dp 基环树)

    传送门 题目描述 放假了,小Z觉得呆在家里特别无聊,于是决定一个人去游乐园玩. 进入游乐园后,小Z看了看游乐园的地图,发现可以将游乐园抽象成有n个景点.m条道路的无向连通图,且该图中至多有一个环(即m ...

  7. 2878: [Noi2012]迷失游乐园 - BZOJ

    Description 放假了,小Z觉得呆在家里特别无聊,于是决定一个人去游乐园玩.进入游乐园后,小Z看了看游乐园的地图,发现可以将游乐园抽象成有n个景点.m条道路的无向连通图,且该图中至多有一个环( ...

  8. Luogu P2081 [NOI2012]迷失游乐园 | 期望 DP 基环树

    题目链接 基环树套路题.(然而各种错误调了好久233) 当$m=n-1$时,原图是一棵树. 先以任意点为根做$dp$,求出从每一个点出发,然后只往自己子树里走时路径的期望长度. 接着再把整棵树再扫一遍 ...

  9. BZOJ 2878([Noi2012]-失落的游乐园树DP+出站年轮加+后市展望DP+vector的erase)

    2878: [Noi2012]迷失乐园 Time Limit: 10 Sec  Memory Limit: 512 MBSec  Special Judge Submit: 319  Solved:  ...

随机推荐

  1. 【IOS学习基础】OC类的相关

    几天前突然在别人的类的.m文件中看到这么一句代码:@synthesize xxxx = _xxxx; 当时愣是没理解啥意思,过后才缓过神来发现原来是把一些类的基础知识忘记了,虽然不用过多去深究以前的一 ...

  2. (转)C# 读取EXCEL文件的三种经典方法

    原文地址http://www.open-open.com/code/view/1420029490093 1.方法一:采用OleDB读取EXCEL文件: 把EXCEL文件当做一个数据源来进行数据的读取 ...

  3. linux安装php5.3

    安装php的依赖包 [root@localhost admin]# unzip libxml2-2.7.8.tar.zip [root@localhost admin]#tar zvxf libxml ...

  4. 在mysql 中两种锁定问题

    mysql 中15.2.10.5 中描述了两个问题,且分别给出了解决办法. 1.向子表中写入数据,但写入之前需确保父表中存在其相应信息. 可能出现,在已经读取父表中的数据,但另一请求将其删除. 办法: ...

  5. Linux--正则表达式--详解

    一.linux文本查找命令 在说linux正规表达式之前,还介绍下linux中查找文本文件常用的三个命令: 1.grep : 最早的文本匹配程序,使用POSIX定义的基本正则表达式(BRE)来匹配文本 ...

  6. JavaScript学习笔记(二)原型

    JavaScript不包含传统的类继承模型,而是使用prototype原型模型.JavaScript使用原型链的继承方式. function Foo() { this.value = 42; } Fo ...

  7. 对简单的正则表达式的理解V1.0

    [^<]* 我得理解也是基本来自官方的解释 [] 我理解是它其中的内容,是指内容哦, 内容是可以选择的 字符 集合 ,比如说  @"<div style="color: ...

  8. GDI+简单现实文字旋转

    原文 http://www.cnblogs.com/kaixiangbb/p/3301272.html 题记 入职新公司已快有两月了,试用期已快结束,项目却迟迟还未正式启动.安排给我的多是些琐事,一直 ...

  9. qt运行库

    KERNEL32.DLL MINGWM10.DLL MSVCRT.DLL LIBGCC_S_DW2-1.DLL QTCORE4.DLL QTGUI4.DLL 笔者安装的是QT SDK.(发行版本这是前 ...

  10. MATLAB介绍

    MATLAB MATLAB[1]  是美国MathWorks公司出品的商业数学软件,用于算法开发.数据可视化.数据分析以及数值计算的高级技术计算语言和交互式环境,主要包括MATLAB和Simulink ...