意甲冠军:

考虑到一棵树,m询价  不要求回答每一次询价u和v通过在两个节点形成的最低等级点路径

思路:

一開始以为是LCA…  只是T了好几次…  后来发现不用LCA也可做

考虑每一个询问u和v  假设他们的lca不是1  则1一定是答案  只是求lca会T  那么我们仅仅须要在遍历树的时候给节点染色  染的颜色就是1的儿子的颜色  假设x这个点在y的子树中(y是1的儿子)那么他的颜色就是y

染完色后我们考虑答案是怎样构成的

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaG91c2VyYWJiaXQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

如图所看到的  答案即是  红色  蓝色  绿色的子树中节点的最小值  那么我们仅仅须要分开三部分求解就可以

定义f[u][x]表示以u为根的子树中第x大的节点标号  这个能够通过树形dp求解  有了这个就能够解决绿色和红色的部分

定义g[u]表示u节点上面到1的路径中旁側的子树的最小节点标号  即图中蓝色部分  也能够利用f做树形dp求解

注意:

题目中不让蓝色部分包括绿色部分  也不把绿色部分放在红色部分中考虑的原因就是u和v节点中的一个可能是1

因为我写的是dfs  杭电会爆栈  所以记得加栈  并用C++提交

代码:

#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 1000010 int f[N][4], g[N], col[N], head[N];
int n, m, color, tot, ans;
struct edge {
int v, next;
} ed[N * 2]; int d(int a, int b) {
if (a < b)
return a;
return b;
} void add(int u, int v) {
ed[tot].v = v;
ed[tot].next = head[u];
head[u] = tot++;
} void dfs1(int u, int fa) {
int i, v;
if (u != 1)
col[u] = color;
for (i = head[u]; ~i; i = ed[i].next) {
v = ed[i].v;
if (u == 1)
color = v;
if (v != fa) {
dfs1(v, u);
f[u][3] = d(v, f[v][0]);
sort(f[u], f[u] + 4);
}
}
} void dfs2(int u, int fa) {
if (fa != 1) {
if (d(u, f[u][0]) != f[fa][0])
g[u] = f[fa][0];
else
g[u] = f[fa][1];
if (g[u] > g[fa])
g[u] = g[fa];
}
int i, v;
for (i = head[u]; ~i; i = ed[i].next) {
v = ed[i].v;
if (v != fa)
dfs2(v, u);
}
} int main() {
int i, j, u, v;
while (~scanf("%d%d", &n, &m)) {
for (i = 1; i <= n; i++) {
f[i][0] = f[i][1] = f[i][2] = f[i][3] = g[i] = N;
head[i] = -1;
}
col[1] = 1;
tot = ans = 0;
for (i = 1; i < n; i++) {
scanf("%d%d", &u, &v);
add(u, v);
add(v, u);
}
dfs1(1, 1);
dfs2(1, 1);
for (i = 1; i <= m; i++) {
scanf("%d%d", &u, &v);
u ^= ans;
v ^= ans;
if (col[u] == col[v]) {
if (u == 1 || v == 1)
ans = 2;
else
ans = 1;
} else {
if (u > v)
swap(u, v);
ans = min(f[v][0], min(g[u], g[v]));
if (u != 1) {
ans = min(ans, f[u][0]);
v = min(col[v], f[col[v]][0]);
u = min(col[u], f[col[u]][0]);
for (j = 0; j < 3; j++) {
if (f[1][j] != u && f[1][j] != v) {
ans = min(ans, f[1][j]);
break;
}
}
} else {
v = min(col[v], f[col[v]][0]);
for (j = 0; j < 3; j++) {
if (f[1][j] != v) {
ans = min(ans, f[1][j]);
break;
}
}
}
}
printf("%d\n", ans);
}
}
return 0;
}

版权声明:本文博主原创文章,博客,未经同意不得转载。

HDU 4916 Count on the path的更多相关文章

  1. HDU 4916 树形dp

    Count on the path Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  2. Count on the path

    Count on the path Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  3. HDU 3336 Count the string(KMP的Next数组应用+DP)

    Count the string Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  4. HDU 5492(DP) Find a path

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5492 题目大意是有一个矩阵,从左上角走到右下角,每次能向右或者向下,把经过的数字记下来,找出一条路径是 ...

  5. HDU 5901 Count primes 论文题

    Count primes 题目连接: http://acm.split.hdu.edu.cn/showproblem.php?pid=5901 Description Easy question! C ...

  6. HDU 4750 Count The Pairs (2013南京网络赛1003题,并查集)

    Count The Pairs Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others ...

  7. hdu 3336 Count the string -KMP&dp

    It is well known that AekdyCoin is good at string problems as well as number theory problems. When g ...

  8. HDU 6470 Count 【矩阵快速幂】(广东工业大学第十四届程序设计竞赛 )

    题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6470 Count Time Limit: 6000/3000 MS (Java/Others)    ...

  9. HDU 4372 Count the Buildings

    Count the Buildings Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Othe ...

随机推荐

  1. surfaceDestroyed什么时候被调用

    今天看别人的代码,突然有个疑问,surfaceDestroyed这个函数什么时候被调用呢? 上网搜了一番,基本都说是surface被销毁的时候,才会调用surfaceDestroyed.问题又来了su ...

  2. Routeros 计划任务连线/断线ADSL

    老板吩咐,要求晚上11点前断网,目的是让大家伙早睡早起. 不想使用Panabit来做策略,阿童木的D2500C还是性能不足,就用ROS的计划任务. 第1步 校时 时间要准,要不控制个乱七八糟. 操作路 ...

  3. android studio学习

    http://blog.csdn.net/ryantang03/article/details/8948037 http://www.it165.net/pro/html/201109/676.htm ...

  4. 人人API 分享到人人功能 修改版

    最近在搞一个日程管理网站, 需要实现分享到人人功能, 所以找了一下人人API, 然后根据自己需要修改了一下. 首先得有一个人人给的js文件, 如下: var Renren = Renren || {} ...

  5. Nutch 二次开发parse纸

    大约nutch基础知识可以参考lemo柱 nutch支持二次开发,为了满足搜索的准确性的问题,内容提取出来作为索引的内容,相应的是parse_text的数据.我使用的事nutch1.4 版本号,在cy ...

  6. Interpolator(插值器)的种类

    Interpolator(插值器)的种类 Interpolator被用来修饰动画效果,定义动画的变化率,可以使存在的动画效果accelerated(加速),decelerated(减速),repeat ...

  7. javascript 正则匹配 提取所有 preg_match_all matchAll方法

    javascript 提取全部的的方法.javascript中没有matchAll这种方法. 用while来实现类似 PHP 中的preg_match_all() :(by default7#zbph ...

  8. 开源Math.NET基础数学类库使用(12)C#随机数扩展方法

    原文:[原创]开源Math.NET基础数学类库使用(12)C#随机数扩展方法                本博客所有文章分类的总目录:http://www.cnblogs.com/asxinyu/p ...

  9. 【BZOJ1791】【IOI2008】【基环树】island(status第一速度)

      1791: [Ioi2008]Island 岛屿  Time Limit: 20 Sec  Memory Limit: 162 MB Submit: 908  Solved: 159 [Su ...

  10. linux并发连接数查看

    1.查看Webserver(Nginx Apache)的并发请求数及其TCP连接状态: netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) pri ...