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的更多相关文章

  1. 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这个 ...

  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) D - Babaei and Birthday Cake 线段树+DP

    题意:做蛋糕,给出N个半径,和高的圆柱,要求后面的体积比前面大的可以堆在前一个的上面,求最大的体积和. 思路:首先离散化蛋糕体积,以蛋糕数量建树建树,每个节点维护最大值,也就是假如节点i放在最上层情况 ...

  6. Codeforces Round #551 (Div. 2) D. Serval and Rooted Tree (树形dp)

    题目链接 题意:给你一个有根树,假设有k个叶子节点,你可以给每个叶子节点编个号,要求编号不重复且在1-k以内.然后根据节点的max,minmax,minmax,min信息更新节点的值,要求根节点的值最 ...

  7. Codeforces Round #343 (Div. 2)

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

  8. 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 ...

  9. 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 ...

随机推荐

  1. spin lock的理解

    为什么在spin lock保护的代码里面不允许有休眠的操作呢? 因为spin lock不是空实现的前提下(内核没关抢占,或者是SMP打开),spin lock中是关抢占的,如果一个进程A拿到锁,内核抢 ...

  2. c语言简单实现telnet客户端

    c语言简单实现telnet客户端 http://blog.csdn.net/haiwenchen/article/details/69944118

  3. git学习笔记三

    1.每个分支的历史版本维护信息位置是.git/logs/refs/heads/master,这个位置的信息是文本文件,不是引用. harvey@harvey-Virtual-Machine:~/dem ...

  4. agc016D - XOR Replace(图论 智商)

    题意 题目链接 给出两个长度为\(n\)的数组\(a, b\) 每次可以将\(a\)中的某个数替换为所有数\(xor\)之和. 若\(a\)数组可以转换为\(b\)数组,输出最少操作次数 否则输出\( ...

  5. 用指定jdk执行jar包

    在运行jar包前执行以下命令,作用是在当前命令行窗口作用域内修改环境变量: export JAVA_HOME=/root/jiabao.gao/Hbase2Redis-1.0.0-SNAPSHOT/j ...

  6. ejs模板在express里的默认文件夹路径修改

    默认的是这句: app.set('view engine','ejs') ===>/views文件夹 我想要变成/websong app.set('views','webosg'); app.s ...

  7. es6字符串模板总结

    我们平时用原生js插入标签或者用node.js写数据库语言时候,经常需要大量的字符串进行转义,很容易出错,有了es6的字符串模板,就再也不用担心会出错了 1.模板中的变量写在${}中,${}中的值可以 ...

  8. Ubuntu Nginx

    如果是阿云的ECS服务器,默认是已经安装了Apache服务器的,但一般都用不到,可以选择将它卸载 sudo service apache2 stop update-rc.d -f apache2 re ...

  9. vue-music 关于Player (播放器组件)--播放和进度条

    迷你播放器 1.播放器组件会在各个页面的情况下会打开. 首先在vuex state.js 中定义全局的播放器状态 import {playMode} from 'common/js/config.js ...

  10. [已解决]#1142 - SELECT command denied to user ''@'localhost' for table 'pma_table_uiprefs'

    症状:在phpmyadmin那边打不开表,提示 #1142 - SELECT command denied to user ''@'localhost' for table 'pma_table_ui ...