HDU5156(离线tarjan+打标记)

Harry and Christmas tree

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

Total Submission(s): 213    Accepted Submission(s): 53

Problem Description

In Christmas Day, Harry got a Christmas tree. The tree has n nodes. And you can assume the tree rooted at node 1. Harry found that there are some gifts with different colors on some nodes. Then Harry began to count the gifts on the tree. Every time Harrty counted
a gift, he written down a pair (a, b) on the paper. Where a indecates which node this gift located, and b indecates the color of this gift. After Harry finished all his counting, for each node x, he wanted to know the number of different kinds of colors that
all gifts located on the subtree rooted at node x had.

Input

There are several test cases,you should process to the end of file.

For each test case, there are two integers n m on the first line, n indecates the number of the nodes, m indecates the number of countings. 1≤n≤50000,1≤m≤500000

The next following n-1 lines. Each line contains two integers a b, it means there is an edge between a and b. 1≤a,b≤n,a≠b.

The next following m lines. Each line contains two integers a b, indecates the countings. 1≤a≤n,1≤b≤100000.

Output

For each test case output one line contains n numbers, where a[i] indecates the number of different kinds of colors that all gifts located on the subtree rooted at node i had.

Sample Input

5 3
3 1
4 1
2 3
5 1
1 9
4 6
4 6

Sample Output

2 0 0 1 0

Hint

Make your program running as fast as possible.

Source

BestCoder Round #25

Recommend

heyang   |   We have carefully selected several similar problems for you:  5157 5154 5153 5152 5151

题意:RT

思路:大概就是打标记,每个点u对从u到树根1上的路径上点贡献为1,在u上+1就好了,这样如果u和v的颜色一样,

那么就会对u和v的最近公共祖先f到树根1上的路径上的点算重复一次,所以只需在f上-1就好了

唯一的坑点是,求最近公共祖先要用离线Tarjan来求,我的这种写法还要加输入挂,否则照样T = =

时间: 2024-10-22 19:16:06

HDU5156(离线tarjan+打标记)的相关文章

POJ - 1470 Closest Common Ancestors(离线Tarjan算法)

1.输出测试用例中是最近公共祖先的节点,以及这个节点作为最近公共祖先的次数. 2.最近公共祖先,离线Tarjan算法 3. /* POJ 1470 给出一颗有向树,Q个查询 输出查询结果中每个点出现次数 */ /* 离线算法,LCATarjan 复杂度O(n+Q); */ #include<iostream> #include<stdio.h> #include<string.h> using namespace std; const int MAXN=1010; co

POJ 1330 Nearest Common Ancestors LCA(在线RMQ,离线Tarjan)

链接:http://poj.org/problem?id=1330 题意:只看题目就知道题目是什么意思了,最近公共祖先,求在一棵树上两个节点的最近公共祖先. 思路:求最近公共祖先有两种算法,在线和离线,在线方法是用RMQ求LCA,一句话总结就是在从DFS时,从第一个点到第二个点的最短路径中深度最浅的点就是公共祖先,用RMQ处理,一般问题的最优解决方式的复杂度是O(NlogN)的预处理+N*O(1)的查询.离线方法是Tarjan算法,将所有询问的两个点都记录下来,在DFS过程中不断将每个点自身作为

POJ 1330 LCA最近公共祖先 离线tarjan算法

题意要求一棵树上,两个点的最近公共祖先 即LCA 现学了一下LCA-Tarjan算法,还挺好理解的,这是个离线的算法,先把询问存贮起来,在一遍dfs过程中,找到了对应的询问点,即可输出 原理用了并查集和dfs染色,先dfs到底层开始往上回溯,边并查集合并 一边染色,这样只要询问的两个点均被染色了,就可以输出当前并查集的最高父亲一定是LCA,因为我是从底层层层往上DSU和染色的,要么没被染色,被染色之后,肯定就是当前节点是最近的 #include <iostream> #include <

[POJ1330]Nearest Common Ancestors(LCA, 离线tarjan)

题目链接:http://poj.org/problem?id=1330 题意就是求一组最近公共祖先,昨晚学了离线tarjan,今天来实现一下. 个人感觉tarjan算法是利用了dfs序和节点深度的关系,大致的意思:dfs如果不递归到递归基,那么dfs就会越递归越深,这个时候深度也是相应增加的,所以这个时候任意在已经遍历过的节点中选取两个点,计算他们的lca也就相当于是用并查集求他们的root.而dfs执行到递归基,转而执行下一个分支的时候,这个时候dfs的节点应当是小于等于之前执行到递归基的节点

LCA(最近公共祖先)——离线 Tarjan 算法

一.梳理概念 定义:对于有根树T的两个结点u.v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u.v的祖先且x的深度尽可能大. 通俗地讲,最近公共祖先节点,就是两个节点在这棵树上深度最大的公共的祖先节点,即两个点在这棵树上距离最近的公共祖先节点. 提示:父亲节点也是祖先节点,节点本身也是它的祖先节点. 给出一棵树,如图所示: 由上面的定义可知:3和5的最近公共祖先为1,5和6的最近公共祖先为2,2和7的最近公共祖先为2, 6和7的最近公共祖先为4. 二.繁文缛节 注意注意注意!!!尚

[HDOJ2586]How far away?(最近公共祖先, 离线tarjan, 并查集)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 这题以前做过…现在用tarjan搞一发…竟然比以前暴力过的慢………… 由于是离线算法,需要Query来保存查询数据,Ans来保存结果.最后输出的时候按照idx的顺序输出,所以胡搞了个排序.. dfs每次更新depth,当前点depth是上一个点累积下来的. 1 /* 2 ━━━━━┒ギリギリ♂ eye! 3 ┓┏┓┏┓┃キリキリ♂ mind! 4 ┛┗┛┗┛┃\○/ 5 ┓┏┓┏┓┃ / 6

POJ - 1986 Distance Queries(离线Tarjan算法)

1.一颗树中,给出a,b,求最近的距离.(我没考虑不联通的情况,即不是一颗树的情况) 2.用最近公共祖先来求, 记下根结点到任意一点的距离dis[],这样ans = dis[u] + dis[v] - 2 * dis[lca(u, v)] 3. /* 离线算法,LCATarjan 复杂度O(n+Q); */ #include<iostream> #include<stdio.h> #include<string.h> using namespace std; const

HDU - 2586 How far away ?(离线Tarjan算法)

1.给定一棵树,每条边都有一定的权值,q次询问,每次询问某两点间的距离. 2.这样就可以用LCA来解,首先找到u, v 两点的lca,然后计算一下距离值就可以了. 这里的计算方法是,记下根结点到任意一点的距离dis[],这样ans = dis[u] + dis[v] - 2 * dis[lca(u, v)] 3. /* 离线算法,LCATarjan 复杂度O(n+Q); */ #include<iostream> #include<stdio.h> #include<stri

求LCA最近公共祖先的离线Tarjan算法_C++

最近一直在刷算法,过几天再来写详细的思路 先丢个模板,这个是用双链树存的 1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 #include<stack> 8 #define N 100001 9 using namespace s