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’s City map looks like a tree (undirected connected acyclic graph) so other people call it Treeland. There are n intersections in the city connected by n - 1 bidirectional roads.
There are m friends of Famil Door living in the city. The i-th friend lives at the intersection ui and works at the intersection vi. Everyone in the city is unhappy because there is exactly one simple path between their home and work.
Famil Door plans to construct exactly one new road and he will randomly choose one among n·(n - 1) / 2 possibilities. Note, that he may even build a new road between two cities that are already connected by one.
He knows, that each of his friends will become happy, if after Famil Door constructs a new road there is a path from this friend home to work and back that doesn't visit the same road twice. Formally, there is a simple cycle containing both ui and vi.
Moreover, if the friend becomes happy, his pleasure is equal to the length of such path (it's easy to see that it's unique). For each of his friends Famil Door wants to know his expected pleasure, that is the expected length of the cycle containing both ui and vi if we consider only cases when such a cycle exists.
Input
The first line of the input contains integers n and m (2 ≤ n, m ≤ 100 000) — the number of the intersections in the Treeland and the number of Famil Door's friends.
Then follow n - 1 lines describing bidirectional roads. Each of them contains two integers ai and bi (1 ≤ ai, bi ≤ n) — the indices of intersections connected by the i-th road.
Last m lines of the input describe Famil Door's friends. The i-th of these lines contain two integers ui and vi (1 ≤ ui, vi ≤ n, ui ≠ vi) — indices of intersections where the i-th friend lives and works.
Output
For each friend you should print the expected value of pleasure if he will be happy. Your answer will be considered correct if its absolute or relative error does not exceed 10 - 6.
Namely: let's assume that your answer is a, and the answer of the jury is b. The checker program will consider your answer correct, if .
Sample Input
4 3
2 4
4 1
3 2
3 1
2 3
4 1
Sample Output
4.00000000
3.00000000
3.00000000
Hint
题意
给一棵树,然后有Q次询问,每次询问给你两个点,问你加一条边之后,这两个点所在的简单环的期望长度是多少
简单环即这两个点在一个环上,这个环是没有重边的。
题解:
两个点u,v,只有3种情况
1.lca(u,v)=v;
这种情况的答案等于v上面的点的距离和除以v上面的点数量+u下面的点距离和除以u下面的点数。
2.lca(u,v)=u;
同上
3.lca(u,v)!=u!=v
这种情况的答案等于v下面的点的距离和除以v下面的点的数量+u下面的点的距离和除以v下面的点的数量。
下面的点的距离和,这个东西,用树形dp去解决就好了。
至于上面的点的距离和,假设lca(u,v)=v这种情况,那么sumUp[v]=sumAll[v]-sumDown[z]-sz[z],z点是v到u的那条路径上的v的儿子。
sumAll[i]是所有点到i点的距离和,sz是这棵子树的大小,sumDown[i]是子树的距离和。
然后这道题就结束了。
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+7;
const int maxm = 20;
int n,m,sz[maxn],lca[maxn][maxm],deep[maxn];
long long sumDown[maxn],sumAll[maxn];
vector<int> E[maxn];
void dfs(int x,int p)
{
sz[x]=1;
sumDown[x]=0;
for(int i=0;i<E[x].size();i++)
{
int v = E[x][i];
if(v==p)continue;
deep[v]=deep[x]+1;
lca[v][0]=x;
for(int j=1;j<maxm;j++)
{
int fa = lca[v][j-1];
if(fa==0)continue;
lca[v][j]=lca[fa][j-1];
}
dfs(v,x);
sumDown[x]+=sumDown[v]+sz[v];
sz[x]+=sz[v];
}
}
void dfs2(int x,int p)
{
for(int i=0;i<E[x].size();i++)
{
int v = E[x][i];
if(v==p)continue;
sumAll[v]=sumAll[x]+n-2*sz[v];
dfs2(v,x);
}
}
void build()
{
dfs(1,-1);
sumAll[1]=sumDown[1];
dfs2(1,-1);
}
int up(int x,int d)
{
for(int i=maxm-1;i>=0;i--)
{
if(d<(1<<i))continue;
x=lca[x][i];
d-=(1<<i);
}
return x;
}
int Lca(int x,int y)
{
if(deep[x]>deep[y])swap(x,y);
y=up(y,deep[y]-deep[x]);
if(x==y)return x;
for(int i=maxm-1;i>=0;i--)
{
if(lca[x][i]!=lca[y][i])
x=lca[x][i],y=lca[y][i];
}
return lca[x][0];
}
void query()
{
int x,y;
scanf("%d%d",&x,&y);
int v = Lca(x,y);
double ans = deep[x]+deep[y]-2*deep[v]+1;
if(x==v)
{
int z = up(y,deep[y]-deep[x]-1);
ans+=(double)(sumAll[x]-sumDown[z]-sz[z])/(n-sz[z]);
}
else
ans+=(double)sumDown[x]/sz[x];
if(y==v)
{
int z = up(x,deep[x]-deep[y]-1);
ans+=(double)(sumAll[y]-sumDown[z]-sz[z])/(n-sz[z]);
}
else
ans+=(double)sumDown[y]/sz[y];
printf("%.12f\n",ans);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<n;i++)
{
int x,y;scanf("%d%d",&x,&y);
E[x].push_back(y);
E[y].push_back(x);
}
build();
while(m--)query();
}
Codeforces Round #343 (Div. 2) E. Famil Door and Roads lca 树形dp的更多相关文章
- Codeforces Round #343 (Div. 2) E. Famil Door and Roads
题目链接: http://www.codeforces.com/contest/629/problem/E 题解: 树形dp. siz[x]为x这颗子树的节点个数(包括x自己) dep[x]表示x这个 ...
- 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 ...
- 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 ...
- Codeforces Round #343 (Div. 2) C. Famil Door and Brackets
题目链接: http://codeforces.com/contest/629/problem/C 题意: 长度为n的括号,已经知道的部分的长度为m,现在其前面和后面补充‘(',或')',使得其长度为 ...
- Codeforces Round #343 (Div. 2) D - Babaei and Birthday Cake 线段树+DP
题意:做蛋糕,给出N个半径,和高的圆柱,要求后面的体积比前面大的可以堆在前一个的上面,求最大的体积和. 思路:首先离散化蛋糕体积,以蛋糕数量建树建树,每个节点维护最大值,也就是假如节点i放在最上层情况 ...
- Codeforces Round #551 (Div. 2) D. Serval and Rooted Tree (树形dp)
题目链接 题意:给你一个有根树,假设有k个叶子节点,你可以给每个叶子节点编个号,要求编号不重复且在1-k以内.然后根据节点的max,minmax,minmax,min信息更新节点的值,要求根节点的值最 ...
- Codeforces Round #343 (Div. 2)
居然补完了 组合 A - Far Relative’s Birthday Cake import java.util.*; import java.io.*; public class Main { ...
- 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 ...
- 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 ...
随机推荐
- C# 判断一个单链表是否有环及环长和环的入口点
1.为什么写这个随笔? 前几天参加一个电面,被问到这个问题,想总结一下. 2.为什么标题强调C#? 想在网上看看代码,却没找到C#版的,于是自己用C#实现一下. 一.解决问题的思路 1.一种比较耗空间 ...
- C#比较两个list集合,两集合同时存在或A集合存在B集合中无
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- 动画基础--基于Core Animation(2)
参考:https://zsisme.gitbooks.io/ios-/content/ 前面的文章动画基础--基于Core Animation(1)提到了图层的基本概念以及可动画参数几何学等知识. 本 ...
- node起server--axios做前端请求----进行CORS--跨域请求
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing). 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从 ...
- windows下tomcat在当前窗口运行,不在新弹出的窗口运行
window下tomcat在当前窗口启动,不在一个新的窗口启动startup.bat中最下几行goto setArgs:doneSetArgscall "%EXECUTABLE%" ...
- NOIP 2012 Day1
tags: NOIP 模拟 倍增 高精 Python categories: 信息学竞赛 总结 Luogu P1079 Vigenère 密码 Solution 表示并不是很懂其他人发的题解. 我是这 ...
- Convolutional Neural Networks卷积神经网络
转自:http://blog.csdn.net/zouxy09/article/details/8781543 9.5.Convolutional Neural Networks卷积神经网络 卷积神经 ...
- Sql server2008中merge用法
/// <summary> /// 修改:添加条件: AND roleModule.FuncCode = tvpRoleModule.FuncCode /// </summary&g ...
- 转载:【知乎Live】狼叔:如何正确的学习Node.js
[知乎Live]狼叔:如何正确的学习Node.js 作者:狼叔:i5ting 原文链接:https://i5ting.github.io/How-to-learn-node-correctly/
- mac安装jdk1.8
一. http://www.oracle.com/technetwork/java/javase/downloads/index.html 去jdk官网下载 二.安装 一路傻瓜式安装,下一步下一步 三 ...