题目链接:

http://www.codeforces.com/contest/629/problem/E

题解:

树形dp。

siz[x]为x这颗子树的节点个数(包括x自己)

dep[x]表示x这个节点的深度,从1开始(其实从什么开始都可以,我们这里用到的只是相对距离)

对于查询u,v,总共有三种情况:

1、u为公共祖先

设x为(u,v)链上u的儿子,则我们知道新边只能从非x子树的点(n-siz[x]连到以v为根的子树上的点(siz[v])

则新边的总条数为(n-siz[x])*siz[v]

现在用树形dp(跑两趟,树形dp的常见用法)可以求出u到(n-siz[x])这些点的距离的和(sd1),以及v到siz[v]这些点的距离的和(sd2)

且(u,v)这条链的长度为Len=dep[u]+dep[v]-2*dep[Lca(u,v)];

组合数学一下,那么答案就是:ans=(sd1*siz[v]+sd2*(n-siz[x])+(n-siz[x])*siz[v]+Len*(n-siz[x])*siz[v])/((n-siz[x])*siz[v])

2、v为公共祖先

同上

3、u,v都不是公共祖先

比上面的更一般化了,把对象(n-siz[x])变成siz[v]就可以了:

ans=(sd1*siz[v]+sd2*siz[u]+siz[u]*siz[v]+Len*siz[u]*siz[v])/(siz[u]*siz[v])

#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std; typedef long long LL;
const int maxn = +;
const int maxm = ; int n, m; vector<int> G[maxn]; int siz[maxn], dep[maxn],lca[maxn][maxm];
LL sdown[maxn],sall[maxn];
void dfs(int u,int fa,int d) {
dep[u] = d, siz[u] = , sdown[u] = ;
lca[u][] = fa;
for (int i = ; i < maxm; i++) {
int f = lca[u][i - ];
lca[u][i] = lca[f][i - ];
}
for (int i = ; i < G[u].size(); i++) {
int v = G[u][i];
if (v == fa) continue;
dfs(v, u, d + );
siz[u] += siz[v];
sdown[u] += siz[v] + sdown[v];
}
}
void dfs2(int u, int fa) {
if (fa == ) sall[u] = sdown[u];
else sall[u] = sall[fa] + n - * siz[u];
for (int i = ; i < G[u].size(); i++) {
int v = G[u][i];
if (v == fa) continue;
dfs2(v, u);
}
} inline void up(int &u,int d){
for (int i = maxm - ; i >= ; i--) {
if (dep[lca[u][i]] >= d) u = lca[u][i];
}
} int Lca(int u, int v) {
if (dep[u] < dep[v]) swap(u, v);
up(u, dep[v]);
if (u == v) return u;
for (int i = maxm - ; i >= ; i--) {
if (lca[u][i] != lca[v][i]) {
u = lca[u][i];
v = lca[v][i];
}
}
return lca[u][];
} void query() {
int u, v;
scanf("%d%d", &u, &v);
int anc = Lca(u, v);
//(u,v)链上的边的贡献+新增的边的贡献
double ans = dep[v] + dep[u] - * dep[anc] + ;
if (anc == v) swap(u, v);
if (anc == u) {
//x为(u,v)链上u的儿子
int x = v; up(x, dep[u] + );
//除x所在子树的点外到所有点的距离的和
LL tmp = sall[u] - sdown[x] - siz[x];
//ans+=(tmp*siz[v]+sdown[v]*(n-siz[x]))/((n-siz[x])*siz[v])
ans += 1.0*tmp / (n - siz[x]) + 1.0*sdown[v] / siz[v];
}
else {
//ans+=(sdown[v]*siz[u]+sdown[u]*siz[v])/(siz[v]*siz[u])
ans += 1.0*sdown[v] / siz[v] + 1.0*sdown[u] / siz[u];
}
printf("%.8lf\n", ans);
} void init() {
for (int i = ; i <= n; i++) G[i].clear();
} int main() {
while (scanf("%d%d", &n, &m) == && n) {
init();
for (int i = ; i < n; i++) {
int u, v;
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
dfs(, , );
dfs2(, );
while (m--) query();
}
return ;
}

Codeforces Round #343 (Div. 2) E. Famil Door and Roads的更多相关文章

  1. Codeforces Round #343 (Div. 2) E. Famil Door and Roads lca 树形dp

    E. Famil Door and Roads 题目连接: http://www.codeforces.com/contest/629/problem/E Description Famil Door ...

  2. Codeforces Round #343 (Div. 2) E. Famil Door and Roads (树形dp,lca)

    Famil Door's City map looks like a tree (undirected connected acyclic graph) so other people call it ...

  3. Codeforces Round #343 (Div. 2) C. Famil Door and Brackets dp

    C. Famil Door and Brackets 题目连接: http://www.codeforces.com/contest/629/problem/C Description As Fami ...

  4. Codeforces Round #343 (Div. 2) C. Famil Door and Brackets

    题目链接: http://codeforces.com/contest/629/problem/C 题意: 长度为n的括号,已经知道的部分的长度为m,现在其前面和后面补充‘(',或')',使得其长度为 ...

  5. Codeforces Round #343 (Div. 2)

    居然补完了 组合 A - Far Relative’s Birthday Cake import java.util.*; import java.io.*; public class Main { ...

  6. Codeforces Round #343 (Div. 2) B. Far Relative’s Problem 暴力

    B. Far Relative's Problem 题目连接: http://www.codeforces.com/contest/629/problem/B Description Famil Do ...

  7. Codeforces Round #343 (Div. 2) B

    B. Far Relative’s Problem time limit per test 2 seconds memory limit per test 256 megabytes input st ...

  8. Codeforces Round #343 (Div. 2) A. Far Relative’s Birthday Cake 水题

    A. Far Relative's Birthday Cake 题目连接: http://www.codeforces.com/contest/629/problem/A Description Do ...

  9. Codeforces Round #343 (Div. 2)-629A. Far Relative’s Birthday Cake 629B. Far Relative’s Problem

    A. Far Relative's Birthday Cake time limit per test 1 second memory limit per test 256 megabytes inp ...

随机推荐

  1. OSPF系列

    实验一.点对点链路上的OSPF 拓扑图 1. 首先配置好路由器R1接口地址和回环地址 2. 配置路由器R2的接口地址和回环地址 3. 配置路由器R3的接口地址和环回地址 4. 配置R1的OSPF协议 ...

  2. 查看EIGRP运行情况详细

    配置EIGRP 在ROUTER(CONFIG)#下 router eigrp autonomous-system-number ROUTER(CONFIG-ROUTER)# network netwo ...

  3. Objective-C设计模式——原型Prototype(对象创建)

    1.原型 原型设计模式所谓原型设计模式,其实就是对象复制,这个特性在所有语言基本上都是存在的. 我们知道在OC中,对象赋值其实是对对象的引用复制,其实就是相当于C语言中的指针.创建了一个新的变量,但是 ...

  4. SQL Server 安装程序失败 不能在控件上调用 Invoke 或 BeginInvoke

    出现这种问题的原因是权限问题,怎么处理呢,使用管理员运行 如果这种方法不行,比如我的就不可以,点击右键 对各个权限对象重新添加完全控制权限. 我的电脑的情况是安装sql2010,然后安装sql管理工具 ...

  5. 20141201--JS Window

    一.window.screen 包含有关用户屏幕的信息. window.screen 对象在编写时可以不使用 window 这个前缀. 一些属性: screen.availWidth - 可用的屏幕宽 ...

  6. (转)RabbitMQ消息队列的小伙伴: ProtoBuf(Google Protocol Buffer)

    什么是ProtoBuf? 一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化.它很适合做数据存储或 RPC 数据交换格式.可用于通讯协议.数据存储等领域的语言无关.平台无关.可扩 ...

  7. java完整的代码执行过程 堆栈+方法区

    07\15-面向对象(static关键字-内存图解)

  8. GDAL Configure in Visual Studio 2010 for Win7/ GDAL+VisualStudio2010 Win7 配置

    配置环境: OS:Win& *86 Ultimate Edition(EN) VS:Visual Studio 2010(EN) Step1: GDAL源码下载:http://www.gisi ...

  9. Linux命令行提示符设置

    我们使用Linux系统时接触最多的是它的命令行窗口,很多时候我们都需要在命令行上输入命令,在输入的命令前都会有提示符,一般系统默认的提示符形式是:[username@host 工作目录]$. 其实,我 ...

  10. mysql 基础知识

    Mysql 远程登录及常用命令 第一招.mysql服务的启动和停止 net stop mysql net start mysql 第二招.登陆mysql 语法如下: mysql -u用户名 -p用户密 ...