题目链接:

Codeforces235D

题目大意:给出一棵基环树,并给出如下点分治过程,求点数总遍历次数的期望。

点分治过程:

1、遍历当前联通块内所有点

2、随机选择联通块内一个点删除掉

3、对新形成的联通块进行点分治

我们设$P(A,B)$表示当删除$A$时$A,B$连通的概率,显然以$A$为分治中心时会遍历到$B$的概率为$P(A,B)$。

那么答案就是$\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}P(i,j)$。

我们先考虑树的情况:

设$A,B$路径上点数(包括$A,B$)为$n$,那么$P(A,B)=\frac{1}{n}$,我们可以用数学归纳法证明:

假设当前$A,B$所处的联通块为$G$且$G$的点数为$x$。

当$n=x$时,即$G$为从$A$到$B$的链,显然只有选$A$为下一个分治中心才能使以$A$为分治中心时会遍历到$B$,所以概率是$\frac{1}{n}$

当$x>n$时,我们假设已经证明$G$的所有包含$A,B$的子联通块的$P(A,B)=\frac{1}{n}$,那么如果这次选取的分治中心在$(A,B)$路径上,概率是$\frac{n}{x}*\frac{1}{n}=\frac{1}{x}$;如果不在$(A,B)$路径上,因为删除这次选取的分治中心后$A,B$所在联通块的$P(A,B)=\frac{1}{n}$,所以概率为$\frac{x-n}{x}*\frac{1}{n}$,两种情况概率相加为$\frac{1}{n}$。

现在再来考虑基环树的情况:

如果$(A,B)$路径不经过环,那么按树的结论解决。

如果$(A,B)$路径经过环,如下图所示。

设橙色点数量为$X$,那么要保证选$A$作为分治中心之前不选橙色点作为分治中心且蓝色点(设数量为$Y$)或绿色点(设数量为$Z$)要有一组点都不在$A$之前作为分治中心,我们分别求出保留橙色点与蓝色点和橙色点与绿色点时的概率再减掉同时保留三个颜色点的概率即为$P(A,B)$,即$P(A,B)=\frac{1}{X+Y}+\frac{1}{X+Z}-\frac{1}{X+Y+Z}$。

将基环树看作是一个环的每个点上挂着一棵树,我们$O(n^2)$枚举两个点判断是否属于一棵树中并计算两点间距离即可。

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int head[5010];
int from[5010];
int to[100010];
int nex[100010];
int dep[5010];
int q[5010];
int cnt;
int vis[5010];
int bel[5010];
int num[100010];
double ans;
int tot;
int x,y,n,m;
int f[5010][17];
void add(int x,int y,int z)
{
nex[++tot]=head[x];
head[x]=tot;
to[tot]=y;
num[tot]=z;
}
bool dfs(int x,int fa)
{
vis[x]=1;
for(int i=head[x];i;i=nex[i])
{
if(num[i]!=fa)
{
if(vis[to[i]])
{
for(int j=x;j!=to[i];j=from[j])
{
q[++cnt]=j;
}
q[++cnt]=to[i];
return true;
}
else
{
from[to[i]]=x;
if(dfs(to[i],num[i]))
{
return true;
}
}
}
}
return false;
}
void find(int x,int fa,int rt)
{
bel[x]=rt;
dep[x]=dep[fa]+1;
f[x][0]=fa;
for(int i=1;i<=15;i++)
{
f[x][i]=f[f[x][i-1]][i-1];
}
for(int i=head[x];i;i=nex[i])
{
if(to[i]!=fa&&!vis[to[i]])
{
find(to[i],x,rt);
}
}
}
int lca(int x,int y)
{
if(dep[x]<dep[y])
{
swap(x,y);
}
int d=dep[x]-dep[y];
for(int i=0;i<=15;i++)
{
if(d&(1<<i))
{
x=f[x][i];
}
}
if(x==y)
{
return x;
}
for(int i=15;i>=0;i--)
{
if(f[x][i]!=f[y][i])
{
x=f[x][i];
y=f[y][i];
}
}
return f[x][0];
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&x,&y);
x++,y++;
add(x,y,i);
add(y,x,i);
}
dfs(1,0);
memset(vis,0,sizeof(vis));
for(int i=1;i<=cnt;i++)
{
vis[q[i]]=1;
}
for(int i=1;i<=cnt;i++)
{
find(q[i],0,i);
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(bel[i]==bel[j])
{
ans+=(double)1/(dep[i]+dep[j]-2*dep[lca(i,j)]+1);
}
else
{
int X=dep[i]+dep[j];
int Y=abs(bel[i]-bel[j])-1;
int Z=cnt-Y-2;
ans+=(double)1/(X+Y)+(double)1/(X+Z)-(double)1/(X+Y+Z);
}
}
}
printf("%.7f",ans);
}

[Codeforces235D]Graph Game——概率与期望+基环树+容斥的更多相关文章

  1. UOJ449. 【集训队作业2018】喂鸽子 [概率期望,min-max容斥,生成函数]

    UOJ 思路 由于最近养成的不写代码的习惯(其实就是懒),以下式子不保证正确性. 上来我们先甩一个min-max容斥.由于每只鸽子是一样的,这只贡献了\(O(n)\)的复杂度. 现在的问题转化为对于\ ...

  2. LOJ2542. 「PKUWC2018」随机游走【概率期望DP+Min-Max容斥(最值反演)】

    题面 思路 我们可以把到每个点的期望步数算出来取max?但是直接算显然是不行的 那就可以用Min-Max来容斥一下 设\(g_{s}\)是从x到s中任意一个点的最小步数 设\(f_{s}\)是从x到s ...

  3. NOIP2019模拟2019.9.20】膜拜大会(外向树容斥,分类讨论)

    传送门. 题解: 我果然是不擅长分类讨论,心态被搞崩了. 注意到\(m<=n-2\),意味着除了1以外的位置不可能被加到a[1]两遍. 先考虑个大概: 考虑若存在\(x,x-1,-,2\)(有序 ...

  4. P4707-重返现世【dp,数学期望,扩展min-max容斥】

    正题 题目链接:https://www.luogu.com.cn/problem/P4707 题目大意 \(n\)个物品,每次生成一种物品,第\(i\)个被生成的概率是\(\frac{p_i}{m}\ ...

  5. 洛谷P5206 [WC2019]数树 [容斥,DP,生成函数,NTT]

    传送门 Orz神仙题,让我长了许多见识. 长式子警告 思路 y=1 由于y=1时会导致后面一些式子未定义,先抓出来. printf("%lld",opt==0?1:(opt==1? ...

  6. luogu 4927 [1007]梦美与线段树 概率与期望 + 线段树

    考场上切了不考虑没有逆元的情况(出题人真良心). 把概率都乘到一起后发现求的就是线段树上每个节点保存的权值和的平方的和. 这个的修改和查询都可以通过打标记来实现. 考场代码: #include < ...

  7. hdu6059 Kanade's trio 字典树+容斥

    转自:http://blog.csdn.net/dormousenone/article/details/76570172 /** 题目:hdu6059 Kanade's trio 链接:http:/ ...

  8. [51Nod1446] 限制价值树 (容斥+MT定理+折半搜索)

    传送门 Description 有N个点(N<=40)标记为0,1,2,...N-1,每个点i有个价值val[i],如果val[i]=-1那么这个点被定义为bad,否则如果val[i] > ...

  9. HDU - 4336:Card Collector(min-max容斥求期望)

    In your childhood, do you crazy for collecting the beautiful cards in the snacks? They said that, fo ...

随机推荐

  1. 深入浅出Tomcat系列

    原本打算一篇文章就发了的,无奈文章太长,阅读压力较大.为了让阅读体验更好一些,还是分多篇吧,大概6篇. 下面是这个主题的目录: 深入浅出Tomcat/1- 来历和配置文件 深入浅出Tomcat/2 - ...

  2. 显式与隐式(ExplicitAndImplicit)

    显式与隐式(Explicit And Implicit) 1.概念 1.1 显式 实现的单词Explicit意思是清楚的.明确的.详述的.所以,显式的“显”是指明显且清楚的实现,相对于接口来说,就是明 ...

  3. Item 21: 比起直接使用new优先使用std::make_unique和std::make_shared

    本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 让我们先从std::make_unique和std::make_s ...

  4. MVC5+EF6 --自定义控制Action访问权限

    本章主要讲解在MVC中灵活控制Action的访问权限: 本章所使用的示例表也是上一张所使用的TbUser.TbRole.TbUserRole: 最终的效果是针对任意一个Action或Controlle ...

  5. NEST.net Client

    NEST.net Client For Elasticsearch简单应用 由于最近的一个项目中的搜索部分要用到 Elasticsearch 来实现搜索功能,苦于英文差及该方面的系统性资料不好找,在实 ...

  6. mysql常用命令行操作(一):登陆、退出、查看端口、修改密码、刷新

    一.登陆和退出mysql mysql -u root -p # 登陆exit # 退出 二.查看当前mysql的端口号 show global variables like 'port'; 三.查看用 ...

  7. Java中List集合去除重复数据的四种方法

    1. 循环list中的所有元素然后删除重复   public static List removeDuplicate(List list) { for ( int i = 0 ; i < lis ...

  8. ToroiseGit提交代码上传到阿里云的Gitlab

    https://blog.csdn.net/xiaomogg/article/details/51903004(copy) 准备 具体过程 准备 1.拥有一个GitHub账户 2.安装了Tortois ...

  9. 五句话搞定JavaScript作用域(ES5)

    JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C# ...

  10. java获取本机ip(排除虚拟机等一些ip)最终解,总算找到方法了

    本文参考https://blog.csdn.net/u011809209/article/details/77236602 本文参考https://blog.csdn.net/yinshuomail/ ...