Count on the path

Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)

Total Submission(s): 92    Accepted Submission(s): 10

Problem Description
bobo has a tree, whose vertices are conveniently labeled by 1,2,…,n.



Let f(a,b) be the minimum of vertices not on the path between vertices a and b.



There are q queries (ui,vi) for the value of f(ui,vi). Help bobo answer them.
 
Input
The input consists of several tests. For each tests:



The first line contains 2 integers n,q (4≤n≤106,1≤q≤106). Each of the following (n - 1) lines contain 2 integers ai,bi denoting an edge between vertices ai and bi (1≤ai,bi≤n).
Each of the following q lines contains 2 integer u′i,v′i (1≤ui,vi≤n).



The queries are encrypted in the following manner.



u1=u′1,v1=v′1.

For i≥2, ui=u′i⊕f(ui - 1,vi - 1),vi=v′i⊕f(ui-1,vi-1).



Note ⊕ denotes bitwise exclusive-or.



It is guaranteed that f(a,b) is defined for all a,b.



The task contains huge inputs. `scanf` in g++ is considered too slow to get accepted. You may (1) submit the solution in c++; or (2) use hand-written input utilities.

 
Output
For each tests:



For each queries, a single number denotes the value.
 
Sample Input
4 1
1 2
1 3
1 4
2 3
5 2
1 2
1 3
2 4
2 5
1 2
7 6
 
Sample Output
4
3
1
 
Author
Xiaoxu Guo (ftiasch)

给定一棵树,求不经过路径的最小标号。

把1作为根,然后增加不经过1,那么答案直接为1,否则就是预处理,

数据规模非常大,所以仅仅能用bfs,而且须要加读写外挂,具体过程代码具体解释。

代码:

/* ***********************************************
Author :rabbit
Created Time :2014/8/6 10:44:17
File Name :5.cpp
************************************************ */
#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <string>
#include <time.h>
#include <math.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define eps 1e-8
#define pi acos(-1.0)
typedef long long ll;
int fun(){
char ch;int flag=1,a=0;
while(ch=getchar())if((ch>='0'&&ch<='9')||ch=='-')break;
if(ch=='-')flag=-1;else a=ch-'0';
while(ch=getchar()){
if(ch>='0'&&ch<='9')a=10*a+ch-'0';
else break;
}
return flag*a;
}
const int maxn=1001000;
int head[maxn],tol;
int subtree[maxn];//子树最小标号
int belong[maxn];//所在的与根节点1相连的子树最小标号。
int child[maxn][4];//儿子子树前4小。
int que[maxn];//广搜队列。
int path[maxn];//path[u]代表u所在的在根节点1的儿子的子树中从根节点到u路径以外的最小标号。
int fa[maxn];//父亲标号。
int dep[maxn];//深度数组
struct Edge{
int next,to;
}edge[2*maxn];
void addedge(int u,int v){
edge[tol].to=v;
edge[tol].next=head[u];
head[u]=tol++;
}
int main()
{
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
int n,m;
while(~scanf("%d%d",&n,&m)){
memset(head,-1,sizeof(head));tol=0;
for(int i=1;i<n;i++){
int u,v;
u=fun();v=fun();
addedge(u,v);
addedge(v,u);
}
int front=0,rear=0;
dep[1]=0;fa[1]=-1;
que[rear++]=1;
while(front!=rear){
int u=que[front++];
for(int i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].to;
if(v==fa[u])continue;
dep[v]=dep[u]+1;
fa[v]=u;
que[rear++]=v;
}
}
for(int i=1;i<=n;i++)
for(int j=0;j<4;j++)
child[i][j]=INF;
for(int i=rear-1;i>=0;i--){
int u=que[i];
subtree[u]=min(u,child[u][0]);
int p=fa[u];
if(p==-1)continue;
child[p][3]=subtree[u];
sort(child[p],child[p]+4);
}
front=0,rear=0;
path[1]=INF;
belong[1]=-1;
for(int i=head[1];i!=-1;i=edge[i].next){
int u=edge[i].to;
path[u]=INF;
belong[u]=subtree[u];
que[rear++]=u;
}
while(front!=rear){
int u=que[front++];
for(int i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].to;
if(v==fa[u])continue;
path[v]=min(path[u],child[u][subtree[v]==child[u][0]]);
belong[v]=belong[u];
que[rear++]=v;
}
path[u]=min(path[u],child[u][0]);//u的儿子子树的最小标号。
}
int last=0;
while(m--){
int u,v;
u=fun();v=fun();
u^=last;v^=last;
if(u>v)swap(u,v);
if(u!=1&&belong[u]==belong[v])last=1;//假设不经过1,而且属于同一个根节点的儿子的子树,答案直接为1
else{
int i=0;
while(child[1][i]==belong[u]||child[1][i]==belong[v])i++;//把包括u,v的儿子子树跳过。
last=u==1?path[v]:min(path[u],path[v]);//路径分为两段,取最小值。
last=min(last,child[1][i]);//出去u,v所在的子树以外的最小值。
}
printf("%d\n",last);
}
}
return 0;
}

HDU 4916 树形dp的更多相关文章

  1. hdu 4123 树形DP+RMQ

    http://acm.hdu.edu.cn/showproblem.php? pid=4123 Problem Description Bob wants to hold a race to enco ...

  2. HDU 1520 树形dp裸题

    1.HDU 1520  Anniversary party 2.总结:第一道树形dp,有点纠结 题意:公司聚会,员工与直接上司不能同时来,求最大权值和 #include<iostream> ...

  3. HDU 1561 树形DP入门

    The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  4. HDU 2196树形DP(2个方向)

    HDU 2196 [题目链接]HDU 2196 [题目类型]树形DP(2个方向) &题意: 题意是求树中每个点到所有叶子节点的距离的最大值是多少. &题解: 2次dfs,先把子树的最大 ...

  5. HDU 1520 树形DP入门

    HDU 1520 [题目链接]HDU 1520 [题目类型]树形DP &题意: 某公司要举办一次晚会,但是为了使得晚会的气氛更加活跃,每个参加晚会的人都不希望在晚会中见到他的直接上司,现在已知 ...

  6. codevs 1380/HDU 1520 树形dp

    1380 没有上司的舞会 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 回到问题 题目描述 Description Ural大学有N个职员 ...

  7. HDU 5834 [树形dp]

    /* 题意:n个点组成的树,点和边都有权值,当第一次访问某个点的时候获得利益为点的权值 每次经过一条边,丢失利益为边的权值.问从第i个点出发,获得的利益最大是多少. 输入: 测试样例组数T n n个数 ...

  8. hdu 4267 树形DP

    思路:先dfs一下,找出1,n间的路径长度和价值,回溯时将该路径长度和价值清零.那么对剩下的图就可以直接树形dp求解了. #include<iostream> #include<al ...

  9. hdu 4607 (树形DP)

    当时比赛的时候我们找出来只要求出树的最长的边的节点数ans,如果要访问点的个数n小于ans距离直接就是n-1 如果大于的话就是(n-ans)*2+ans-1,当时求树的直径难倒我们了,都不会树形dp ...

随机推荐

  1. Java调用摄像头截图

    使用webcam-capture替换JMF调用摄像头 最近有个需要通过java调用摄像头,并截图的需求,在网上找了下资料,大部分是用一个叫jmf的库,但是jmf已经几百年没有更新,用起来各种问题.后来 ...

  2. jstl的小问题

    jstl试了半天,终于知道错在哪里了! 这是jsp中的代码 从select中取得user_id:看清楚了 是user_id:小写第一位; <table width="50%" ...

  3. 关于java mail 发邮件的问题总结(转)

    今天项目中有需要用到java mail发送邮件的功能,在网上找到相关代码,代码如下: import java.io.IOException; import java.util.Properties; ...

  4. SO_REUSEADDR 套接字选项应用

    在网络上的SO_REUSEADDR套接字选项是用来解决地址问题重用了大量的信息.但仅仅停留在文字的表达.并没有实例,非常easy误导谁刚开始学习,和不解,此处不再赘述. 的使用该选项,以及须要注意的问 ...

  5. python学习之print输出不换行

    print的即时打印会导致换行,要使得print的输出不换行,可以在字符串或者变量后面加个逗号(“,”),如下: s = "A bird in the hand..." for c ...

  6. java.lang.NoClassDefFoundError: org/apache/juli/logging/LogFactory

    Myeclipse 8.6使用tomcat7时间.执行javaweb如报告了以下错误项: java.lang.NoClassDefFoundError: org/apache/juli/logging ...

  7. Objective-C路成魔【18-复制对象】

    郝萌主倾心贡献,尊重作者的劳动成果,请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠,支持郝萌主,捐赠数额任意.重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 将一个变量 ...

  8. hihocoder第42周 k*N骨牌覆盖(状态dp+矩阵快速幂)

    上周的3*N的骨牌,因为状态只有8中,所以我们可以手算出状态转移的矩阵 但是这周是k*N,状态矩阵不好手算,都是我们改成用程序自动生成一个状态转移的矩阵就行了,然后用这个矩阵进行快速幂即可 枚举枚举上 ...

  9. Android开发之使用Handler封装下载图片工具类(源码分享)

    假设每下载一张图片,就得重写一次Http协议,多线程的启动和handler的信息传递就显得太麻烦了,我们直接来封装一个工具类,便于我们以后在开发时随时能够调用. (1)在清单文件加入权限 <us ...

  10. iOS 在TabViewController中的一个ViewController跳转到另一种ViewController

    第一步: #import "AppDelegate.h" 步骤二: 在须要跳转的地方: AppDelegate *appDelegate = (AppDelegate *)[[UI ...