http://www.lydsy.com/JudgeOnline/problem.php?id=2878

题意:n个点的图,保证图联通,有n-1或者n条边,求从任意一个点出发,不经过相同点,最终无路可走的路径长度期望。

思路:m=n-1时,可以用dp,处理出i点往下,i点往上走的路径长度期望,然后O(n)统计就可以了。

m=n时,由于环上点点数不超过20,那这就是基环树,我们考虑枚举基环树上面的点i,假设我们到了i,并走向了i的子树。

这样我们就把环断开了,然后我们再两遍顺逆走这个环,就可以处理出up数组了,然后再分别下传到每个子树里。

 #include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
int flag,n,m,f[],len[],vis[],tot,go[],next[],cnt,cir[],huan[],first[],val[],du[];
double down[],up[];
int read(){
char ch=getchar();int t=,f=;
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (''<=ch&&ch<=''){t=t*+ch-'';ch=getchar();}
return t*f;
}
void insert(int x,int y,int z){
tot++;
go[tot]=y;
next[tot]=first[x];
first[x]=tot;
val[tot]=z;
}
void add(int x,int y,int z){
insert(x,y,z);insert(y,x,z);
}
void dfs1(int x,int fa){
vis[x]=;
for (int i=first[x];i;i=next[i]){
int pur=go[i];
if (vis[pur]) continue;
dfs1(pur,x);
down[x]+=(double)val[i]+(((double)down[pur])/((double)(du[pur]-+(du[pur]==))));
}
}
void dfs2(int x,int fa){
if (!cir[x]&&fa!=) up[x]=len[x]+((double)((double)up[fa]+down[fa]-len[x]-((double)down[x])/((double)du[x]-+(du[x]==))))/((double)(du[fa]-+(du[fa]==)));
vis[x]=;
for (int i=first[x];i;i=next[i]){
int pur=go[i];
if (vis[pur]) continue;
f[pur]=x;
len[pur]=val[i];
dfs2(pur,x);
}
}
void work1(){
dfs1(,);
for (int i=;i<=n;i++) vis[i]=;
dfs2(,);
double ans=;
for (int i=;i<=n;i++) ans+=((double)down[i]+(double)up[i])/((double)du[i]);
ans/=((double)(n));
printf("%.5f\n",ans);
}
void dfs(int x,int fa){
vis[x]=;
for (int i=first[x];i;i=next[i]){
int pur=go[i];
if (flag) return;
if (f[x]!=pur&&vis[pur]){
len[pur]=val[i];
int j=x;
while (j!=f[pur]){
cnt++;
cir[j]=;
huan[cnt]=j;
j=f[j];
}
flag=;
return;
}else if (!vis[pur]){
len[pur]=val[i];
f[pur]=x;
dfs(pur,x);
}
}
}
void work2(){
flag=;
dfs(,);cnt++;
for (int i=;i<=n;i++) vis[i]=;
for (int i=;i<cnt;i++) vis[huan[i]]=;
for (int i=;i<cnt;i++) dfs1(huan[i],);
for (int i=;i<cnt;i++){
int x=(i+)%cnt;double s=;
while (x!=i){
if ((x+)%cnt==i) up[huan[i]]+=(double)s*len[huan[(x-+cnt)%cnt]]+((double)(s*down[huan[x]]))/((double)(du[huan[x]]-+(du[huan[x]]==)));
else up[huan[i]]+=(double)s*len[huan[(x-+cnt)%cnt]]+((double)(s*down[huan[x]]))/((double)(du[huan[x]]-));
s=s/((double)(du[huan[x]]-));
x=(x+)%cnt;
}
x=(i-+cnt)%cnt;s=;
while (x!=i){
if ((x-+cnt)%cnt==i) up[huan[i]]+=(double)s*len[huan[x]]+((double)(s*down[huan[x]]))/((double)(du[huan[x]]-+(du[huan[x]]==)));
else up[huan[i]]+=(double)s*len[huan[(x)%cnt]]+((double)(s*down[huan[x]]))/((double)(du[huan[x]]-));
s=s/((double)(du[huan[x]]-));
x=(x-+cnt)%cnt;
}
}
for (int i=;i<=n;i++) vis[i]=;
for (int i=;i<cnt;i++) vis[huan[i]]=;
for (int i=;i<cnt;i++) dfs2(huan[i],);
double ans=;
for (int i=;i<=n;i++) ans+=(down[i]+up[i])/(du[i]);
printf("%.5f\n",ans/n);
}
int main(){
cnt=-;
n=read();m=read();flag=;
for (int i=;i<=m;i++){
int x=read(),y=read(),z=read();
add(x,y,z);
du[x]++;du[y]++;
}
if (m==n-) work1();
else work2();
}

BZOJ 2878 迷失游乐园的更多相关文章

  1. 【NOI2012】迷失游乐园

    题目链接:迷失游乐园(BZOJ)  迷失游乐园(Luogu) 独立完成的题,写一发题解纪念一波~ 模拟完样例大概可以知道是道树形DP了. 观察数据范围,发现是基环树,至少会有一个环. 先从树的部分开始 ...

  2. 【BZOJ】【2878】【NOI2012】迷失游乐园

    树形+基环树DP/数学期望 然而我并不会做…… 题解戳这里:http://blog.csdn.net/u011265346/article/details/46328543 好吧先考虑一个简单点的,当 ...

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

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

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

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

  5. BZOJ 2878 【NOI2012】 迷失游乐园

    题目链接:迷失游乐园 这道题也没有传说中的那么难写吗→_→ 似乎有篇博客讲得特详细……附上链接:戳这里 如果这道题不是基环树,而就是一棵树的话,我们来考虑改怎么做.因为树上的路径只有向上.向下两种走法 ...

  6. 【BZOJ2878】【NOI2012】迷失游乐园(动态规划)

    [BZOJ2878][NOI2012]迷失游乐园(动态规划) 题面 BZOJ 题解 记得以前考试的时候做过这道题目 这题的暴力还是非常显然的,每次\(dfs\)一下就好了. 时间复杂度\(O(n^2) ...

  7. [bzoj2878][Noi2012]迷失游乐园(基环树dp)

    [bzoj2878][Noi2012]迷失游乐园(基环树dp) bzoj luogu 题意:一颗数或是基环树,随机从某个点开始一直走,不走已经到过的点,求无路可走时的路径长期望. 对于一棵树: 用两个 ...

  8. 「NOI2012」迷失游乐园

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

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

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

随机推荐

  1. layout cannot be resolved or is not a field

    去除代码activity代码页面顶部中的 import android.R;这句就可以消除红色波浪线的main cannot be resolved or is not a field类似这个错误了

  2. cf B. Fixed Points

    http://codeforces.com/contest/347/problem/B #include <cstdio> #include <cstring> #includ ...

  3. 商派shopex

    http://www.shopex.cn/48release/shopexsingle_exper.php 在线体验 前台体验:http://demo.shopex.com.cn/485 后台体验:h ...

  4. 查看登录用户who

    几个命令:wwho每隔5秒钟,就来查看hadoop是否已经登录,如登录,显示其已经登录,并退出:sleep whoami last,显示/var/log/wtmp文件,显示用户登录历史及系统重启历史  ...

  5. Visual Studio 2015 使用ODP.net进行EF开发

    刚转了新公司,以前公司都是用VS+MSSQL作为开发工具的 现在新公司由于数据库是Oracle,而且新公司比较小规模,开发团队也没有什么规范 访问数据库的方式一直使用ADO.net的DataTable ...

  6. RDBMS 数据库补丁集补丁号码高速參考-文档 ID 1577380.1

    保存此文,高速查询补丁号 Oracle Database - Enterprise Edition - 版本号 8.1.7.0 和更高版本号 本文档所含信息适用于全部平台 补丁集/PSU 补丁号码   ...

  7. JS正则表达式---分组

    JS正则表达式---分组 之前写了一篇关于正则新手入门的文章,本以为对正则表达式相对比较了解 但是今天我又遇到了一个坑,可能是自己不够细心的原因吧,今天就着重和大家分享一下javascript正则表达 ...

  8. Emacs入门快捷键

    打开emacs开始一个程序最基本操作: 1.打开Emacs,执行 $ emacs 2.建立一个新的程序文件. 按C-x C-f 然后在屏幕的底部出现minibuffer,光标提示你输入文件名称, 文件 ...

  9. Ubuntu14.04配置arm-linux-gcc 4.4.3交叉编译环境

    首先下载交叉编译:不多说,直接贴地址了 http://arm9download.cncncn.com/mini2440/linux/arm-linux-gcc-4.4.3-20100728.tar.g ...

  10. (转)在Eclipse中使用JUnit4进行单元测试

    原地址:http://blog.csdn.net/andycpp/article/details/1327147