意甲冠军:

考虑到一棵树,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. MySQL 批量Dll操作(转)

    概述 本章节介绍使用游标来批量进行表操作,包括批量添加索引.批量添加字段等.如果对存储过程.变量定义.预处理还不是很熟悉先阅读我前面写过的关于这三个概念的文章,只有先了解了这三个概念才能更好的理解这篇 ...

  2. vs修错小知识,相当于我自己的笔记,需要的人可以看下

    在出现这种外部错误时,首先得检查你自己的的类的方法是否都以及实现了,我就是出现没有实现某些方法所以报出这个错误!!! 结果是onExit()方法我定义了没有去实现它. (待续)

  3. ZeroBrane Studio远程调试Lua程序(转)

    环境: ZeroBrane Studio安装在Windows 7上,而要调试的程序运行在CentOS上: 设置: 在windows 7上,打开ZeroBrane Studio,打开需要调试的文件,例如 ...

  4. Android使得手机拍照功能的发展(源共享)

    Android系统调用手机拍照功能有两种方法来直接调用手机自带摄像头还有一个就是要当心自己的节拍. 例Camera360 强大的一个在每个操作系统都有一个手机摄影软件:您可以捕捉不同风格,不同特效的照 ...

  5. rsync 只是测试,请看下一篇

    实现从客户服务器去同步资源服务器 1.解压 # tar -xzpvf rsync-2.5.6.tar.gz   编译安装 # cd rsync-2.5.6/  # ./configure --pref ...

  6. Swift新手教程3-字符串String

    原创blog,转载请注明出处 String 在swfit中,String兼容Unicode的方式.用法和C语言类似. 注意   在Cocoa和Cocoa touch中,Swift的String,和Fo ...

  7. UVA 12103 - Leonardo&#39;s Notebook(数论置换群)

    UVA 12103 - Leonardo's Notebook 题目链接 题意:给定一个字母置换B.求是否存在A使得A^2=B 思路:随意一个长为 L 的置换的k次幂,会把自己分裂成gcd(L,k) ...

  8. Swing中弹出对话框的几种方式(转)

    http://www.cnblogs.com/mailingfeng/archive/2011/12/28/2304289.html 在swing中,基于业务的考量,会有对话框来限制用户的行为及对用户 ...

  9. Spring HTTPInvoker原理猜想(HTTP+序列化)

    没有查看源码,仅作参考 实现步骤: 一,客户端 (1),远程调用信息封装为远程调用对象 (2),序列化写入到远程调用HTTP请求中 (3),向服务器发送 (4),服务器端返回的HTTP响应结果 (5) ...

  10. Web指纹识别目的Discuz识别+粗糙的版本演绎

    这个识别程序是本学期在我的职业培训项目.它是做一类似至Zoomeye怪东西,然后使用ES集成,为了让搜索引擎寻找.因此,我们必须首先去网上识别相应的能力Web包裹,如果用户输入的关键词:Discuz ...