POJ 1330 (LCA)

http://poj.org/problem?id=1330

题意:给出一个图,求两个点的最近公共祖先。

sl :水题,贴个模板试试代码。本来是再敲HDU4757的中间发现要用LCA,  操蛋只好用这个题目试试自己写的对不对。 下面是个倍增的写法,挺实用的。

好了,继续。。。

1 #include <cstdio>
 2 #include <cstring>
 3 #include <vector>
 4 #include <algorithm>
 5 #include <map>
 6 #include <cmath>
 7 using namespace std;
 8 const int MAX = 1e4+10;
 9 vector<int> G[MAX];
10 int is_root[MAX];
11 int parent[15][MAX],dep[MAX];
12 int n,m;
13 void add_edge(int from,int to) {
14     G[from].push_back(to);
15     G[to].push_back(from);
16 }
17 void dfs(int u,int pre,int d) {
18     dep[u]=d; parent[0][u]=pre;
19     for(int i=0;i<G[u].size();i++) {
20         int v=G[u][i];
21         if(v!=pre) dfs(v,u,d+1);
22     }
23     return ;
24 }
25 void init() {
26     int x;
27     for(int i=1;i<=n;i++) {
28         if(is_root[i]) {
29             x=i; break;
30         }
31     }
32 
33     dfs(x,-1,0);
34     for(int k=0;k<14;k++) {
35         for(int v=1;v<=n;v++) {
36             if(parent[k][v]<0) parent[k+1][v]=-1;
37             else parent[k+1][v]=parent[k][parent[k][v]];
38         }
39     }
40 }
41 int LCA(int u,int v) {
42     if(dep[u]>dep[v]) swap(u,v);
43     for(int k=0;k<15;k++) {
44         if((dep[v]-dep[u])>>k&1) v=parent[k][v];
45     }
46     if(u==v) return u;
47     for(int k=14;k>=0;k--) {
48         if(parent[k][u]!=parent[k][v]) {
49             u=parent[k][u]; v=parent[k][v];
50         }
51     }
52     return parent[0][u];
53 }
54 void CLEAR() {
55     for(int i=0;i<MAX;i++) G[i].clear();
56 }
57 int main() {
58     int cas; int a,b;
59     scanf("%d",&cas);
60     while(cas--) {
61         CLEAR();
62         scanf("%d",&n);
63         memset(is_root,true,sizeof(is_root));
64         for(int i=1;i<=n-1;i++) {
65             scanf("%d %d",&a,&b);
66             add_edge(a,b);
67             is_root[b]=false;
68         }
69         init();
70         scanf("%d %d",&a,&b);
71         int ans=LCA(a,b);
72         printf("%d\n",ans);
73     }
74     return 0;
75 }

SB CODE

时间: 2024-09-30 20:16:00

POJ 1330 (LCA)的相关文章

POJ 1330(LCA模板)

链接:http://poj.org/problem?id=1330 题意:q次询问求两个点u,v的LCA 思路:LCA模板题,首先找一下树的根,然后dfs预处理求LCA(u,v) AC代码: 1 #include<iostream> 2 #include<algorithm> 3 #include<cmath> 4 #include<cstring> 5 #include<set> 6 #include<string> 7 #incl

最近公共祖先(lca)

囧啊囧. lca的求法太多了 倍增,tarjan,st,lct,hld.... 后边三个我就不写了,其中st我没写过,估计用不上,在线用倍增,离线用tarjan就行了. 嗯. 第一种,倍增(nlogn,在线): 倍增的思想用在树上,即可以求出lca. 我们维护二维数组,f[i][j],表示i号点的第2^j号祖先,显然2^0=1也就是f[i][0]就是他的父亲 我们需要用dfs维护一个深度数组(求lca需要用) 还需要倍增求出所有的f[i][j],学过st的都应该知道,在这里f[i][j]=f[

洛谷P3379 【模板】最近公共祖先(LCA)

P3379 [模板]最近公共祖先(LCA) 152通过 532提交 题目提供者HansBug 标签 难度普及+/提高 提交  讨论  题解 最新讨论 为什么还是超时.... 倍增怎么70!!题解好像有倍- 题面这个地方写错了 无论是用RMQ+dfs还是tarjan- 为什么我的倍增超时了 求助!为什么只有70分 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接

最近公共祖先问题(LCA)模板

最近公共祖先问题(LCA)是求一颗树上的某两点距离他们最近的公共祖先节点,由于树的特性,树上两点之间路径是唯一的,所以对于很多处理关于树的路径问题的时候为了得知树两点的间的路径,LCA是几乎最有效的解法. 首先是LCA的倍增算法.算法主体是依靠首先对整个树的预处理DFS,用来预处理出每个点的直接父节点,同时可以处理出每个点的深度和与根节点的距离,然后利用类似RMQ的思想处理出每个点的 2 的幂次的祖先节点,这就可以用 nlogn 的时间完成整个预处理的工作.然后每一次求两个点的LCA时只要对两个

POJ 2253-Frogger (Prim)

题目链接:Frogger 题意:两只青蛙,A和B,A想到B哪里去,但是A得弹跳有限制,所以不能直接到B,但是有其他的石头作为过渡点,可以通过他们到达B,问A到B的所有路径中,它弹跳最大的跨度的最小值 PS:最小生成树过的,刚开始用Dijstra做,Kao,精度损失的厉害,对于Dijksra的变形不大会变啊,看了Discuss有人用最小生成树过,我一划拉,还真是,敲了,就过了,等会研究研究最短路的各种变形,有模板不会变,不会灵活应用,渣渣就是渣渣. ME               Time 10

poj 1861(最小生成树)

Description Andrew is working as system administrator and is planning to establish a new network in his company. There will be N hubs in the company, they can be connected to each other using cables. Since each worker of the company must have access

POJ 2352 (stars)

[题意描述] 就是给定n个星星的x,y坐标,y坐标按照从小到大的顺序进行排列,x坐标随机排列.下面求对于每个星星而言,其它星星的x,y的坐标都小于等于该星星的数目,然后输出所有的情况. [思路分析] 我们这道题可以采用树状数组求解,将x+1作为树状数组的底标. [AC代码] #include<iostream> #include<bitset> #include<cstdio> #include<cstring> #include<algorithm&

poj Sudoku(数独) DFS

Sudoku Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 13665   Accepted: 6767   Special Judge Description Sudoku is a very simple task. A square table with 9 rows and 9 columns is divided to 9 smaller squares 3x3 as shown on the Figure.

【原创】洛谷 LUOGU P3379 【模板】最近公共祖先(LCA) -&gt; 倍增

P3379 [模板]最近公共祖先(LCA) 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每行包含两个正整数x.y,表示x结点和y结点之间有一条直接连接的边(数据保证可以构成树). 接下来M行每行包含两个正整数a.b,表示询问a结点和b结点的最近公共祖先. 输出格式: 输出包含M行,每行包含一个正整数,依次为每一个询问的结果. 输入输出样例 输入