一棵树的话直接树形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. ORACLE 主要后台进程1

    Oracle Database Background Processes: 1.Database writer (DBWn)The database writer writes modified bl ...

  2. Slf4j的包冲突

    异常信息:Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.apache.log4j.Log4jLog ...

  3. 调用Response.Redirect 捕获异常 解决办法(摘抄)

    如果使用 Response.End.Response.Redirect 或 Server.Transfer 方法,将出现 ThreadAbortException 异常.您可以使用 try-catch ...

  4. tabbedApliction

    一.手动创建UITabBarController 最常见的创建UITabBarController的地方就是在application delegate中的 applicationDidFinishLa ...

  5. 解决OpenWrt多拨刚开机拨号只拨上一次问题

    红色标注为需要权限755/etc/ppp/ip-up.d/ip-up: 一旦 PPP 连结建立后, pppd 会找寻 /etc/ppp/ip-up 指令稿 如果这个指令稿存在并且可以执行的话,那么 P ...

  6. Spring-----代码中使用注入的Properties配置属性

    转载自:http://blog.csdn.net/hekewangzi/article/details/49990799

  7. java之集合类特性对比分析列表

    类集合框架有很多文章都列出了继承关系图,但是我没有找到更清晰的特性对比图,我这里根据使用选择条件总结对比罗列一下它们之间的一些特点.

  8. 设计模式之适配器模式(Decorator)

    1.意图 动态地给一个对象添加一些额外的功能. 2.适用性 动态.透明的方式给单个对象添加职责. 如果不适合适用子类来进行扩展的时候,可以考虑适用装饰模式. 避免子类数目爆炸性增长. 3.结构 4.参 ...

  9. Python面向对象关系

    首先了解一下Python面向对象中类型-实例和父类-子类的关系.下面的一些规则很有用. 当我们介绍许多不同的对象时,我们只用了两种关系(图4.1 关系): 是一类(is a kind of)(实线): ...

  10. strcat()的编写

    1.strcat() #include <windows.h> #include <assert.h> #include <iostream> //strcat() ...