LCA(最近公共祖先)模板
Tarjan版本
/* gyt
Live up to every day */
#pragma comment(linker,"/STACK:1024000000,1024000000")
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<cstring>
#include<queue>
#include<set>
#include<string>
#include<map>
#include <time.h>
#define PI acos(-1)
using namespace std;
typedef long long ll;
typedef double db;
const int maxn = 1e5+;
const ll maxm = 1e7;
const ll base = ;
const int INF = <<;
const db eps = 1e-;
const ll mod = 1e9+;
struct Edge{
int u, v, next, val;
}edge[maxn*], edge1[maxn*];
int n, m;
int head[maxn], head1[maxn];
int father[maxn], dis[maxn], tol, toll, LCA[maxn];
bool visit[maxn];
int cnt;
//LCA[]最近公共祖先 void init() {
cnt=;
memset(head, -, sizeof(head));
memset(head1, -, sizeof(head1));
tol=toll=;
memset(visit, , sizeof(visit));
memset(LCA, , sizeof(LCA));
memset(dis, , sizeof(dis));
}
void add(int u, int v, int w) {
edge[tol].u=u, edge[tol].v=v,edge[tol].val=w;
edge[tol].next=head[u];
head[u]=tol++;
}
void add1(int u, int v, int w) {
edge1[toll].u=u, edge1[toll].v=v,edge1[toll].val=w;
edge1[toll].next=head1[u];
head1[u]=toll++;
}
int Find(int x) {
if (x!=father[x]) father[x]=Find(father[x]);
return father[x];
}
void tarjan(int u) {
visit[u]=;
father[u]=u;
for (int j=head1[u]; ~j; j=edge1[j].next) {
int v=edge1[j].v;
if (visit[v]) LCA[edge1[j].val]=Find(v);
}
for (int j=head[u]; ~j; j=edge[j].next) {
int v=edge[j].v;
if (!visit[v]) {
dis[v]=dis[u]+edge[j].val;
tarjan(v);
father[v]=u;
//cout<<dis[v]<<endl;
}
}
}
void solve() {
init();
scanf("%d%d", &n, &m);
for (int i=; i<n; i++) {
int a, b, c; scanf("%d%d%d", &a, &b, &c);
add(a, b, c); add(b, a, c);
}
for (int i=; i<m; i++) {
int a, b; scanf("%d%d", &a, &b);
add1(a, b, i); add1(b, a, i);
}
dis[]=;
tarjan();
for(int i=;i<toll;i+=){
printf("%d\n",LCA[edge1[i].val]);
}
}
int main() {
int t = ;
//freopen("in.txt","r",stdin);
// freopen("gcd.out","w",stdout);
scanf("%d", &t);
while(t--)
solve();
return ;
}
倍增版本
/* gyt
Live up to every day */
#pragma comment(linker,"/STACK:1024000000,1024000000")
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<cstring>
#include<queue>
#include<set>
#include<string>
#include<map>
#include <time.h>
#define PI acos(-1)
using namespace std;
typedef long long ll;
typedef double db;
const int maxn = 1e5+;
const ll maxm = 1e7;
const ll base = ;
const int INF = <<;
const db eps = 1e-;
const ll mod = 1e9+;
struct Edge{
int u, v, next, val;
}edge[maxn*];
int head[maxn], dis[maxn];
int f[maxn], deep[maxn], p[maxn][];
int n, m, cnt; void init() {
int i,j;
for(j=;(<<j)<=n;j++)
for(i=;i<=n;i++)
p[i][j]=-;
for(i=;i<=n;i++)p[i][]=f[i];
for(j=;(<<j)<=n;j++)
for(i=;i<=n;i++)
if(p[i][j-]!=-)
p[i][j]=p[p[i][j-]][j-];//i的第2^j祖先就是i的第2^(j-1)祖先的第2^(j-1)祖先
}
void add(int u, int v, int w) {
edge[cnt].u=u, edge[cnt].v=v;
edge[cnt].next=head[u], edge[cnt].val=w;
head[u]=cnt++;
}
void dfs(int u, int pre, int t) {
deep[u]=t;
f[u]=pre;
for (int i=head[u]; ~i; i=edge[i].next) {
int v=edge[i].v;
if (v!=pre) {
dis[v]=dis[u]+edge[i].val;
dfs(v, u, t+);
}
}
}
int lca(int a, int b) {
int i, j;
if (deep[a]<deep[b]) swap(a, b);
for ( i=; (<<i)<=deep[a]; i++);
i--;
for ( j=i; j>=; j--) {
if (deep[a]-(<<j)>=deep[b]) a=p[a][j];
}
if (a==b) return a;
for ( j=i; j>=; j--) {
if (p[a][j]!=- && p[a][j]!=p[b][j]) {
a=p[a][j], b=p[b][j];
}
}
return f[a];
}
void solve() {
scanf("%d%d", &n, &m);
cnt=;
memset(head, -, sizeof(head));
for (int i=; i<n-; i++) {
int a, b, c; scanf("%d%d%d", &a, &b, &c);
add(a, b, c); add(b, a, c);
}
dis[]=;
dfs(, -, );
init();
for (int i=; i<m; i++) {
int a, b; scanf("%d%d", &a, &b);
int ans=dis[a]+dis[b]-*dis[lca(a, b)];
printf("%d\n", ans);
}
}
int main() {
int t = ;
// freopen("in.txt","r",stdin);
// freopen("gcd.out","w",stdout);
scanf("%d", &t);
while(t--)
solve();
return ;
}
LCA(最近公共祖先)模板的更多相关文章
- LCA最近公共祖先模板(求树上任意两个节点的最短距离 || 求两个点的路进(有且只有唯一的一条))
原理可以参考大神 LCA_Tarjan (离线) TarjanTarjan 算法求 LCA 的时间复杂度为 O(n+q) ,是一种离线算法,要用到并查集.(注:这里的复杂度其实应该不是 O(n+q) ...
- LCA最近公共祖先模板代码
vector模拟邻接表: #include<iostream> #include<cstdio> #include<cstring> #include<cma ...
- lca最短公共祖先模板(hdu2586)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 #include<iostream> #include<cstdio> ...
- LCA(最近公共祖先)之倍增算法
概述 对于有根树T的两个结点u.v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u.v的祖先且x的深度尽可能大. 如图,3和5的最近公共祖先是1,5和2的最近公共祖先是4 在本篇中我们先介 ...
- lca 最近公共祖先
http://poj.org/problem?id=1330 #include<cstdio> #include<cstring> #include<algorithm& ...
- Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载)
Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载) 转载自:http://hi.baidu.com/lydrainbowcat/blog/item/2 ...
- CodeVs.1036 商务旅行 ( LCA 最近公共祖先 )
CodeVs.1036 商务旅行 ( LCA 最近公共祖先 ) 题意分析 某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间. 假设有N个城镇,首都编号为1,商人从 ...
- LCA近期公共祖先
LCA近期公共祖先 该分析转之:http://kmplayer.iteye.com/blog/604518 1,并查集+dfs 对整个树进行深度优先遍历.并在遍历的过程中不断地把一些眼下可能查询到的而 ...
- LCA 近期公共祖先 小结
LCA 近期公共祖先 小结 以poj 1330为例.对LCA的3种经常使用的算法进行介绍,分别为 1. 离线tarjan 2. 基于倍增法的LCA 3. 基于RMQ的LCA 1. 离线tarjan / ...
随机推荐
- Websocket实现群聊、单聊
Websocket 使用的第三方模块:gevent-websocket 群聊 ws群聊.py中的内容 from flask import Flask, request, render_template ...
- word2vec详解与实战
有那么一句话 不懂word2vec,就别说自己是研究人工智能->机器学习->自然语言处理(NLP)->文本挖掘的 所以接下来我就从头至尾的详细讲解一下word2vec这个东西. 简要 ...
- TOJ1698/POJ3264Balanced Lineup (线段树 or RMQ-ST)
传送门:http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=1698 时间限制(普通/Java): ...
- 微信小程序开发——小程序分享转发
关于小程序的转发: 最简单的就是点击小程序右上角菜单“转发”按钮直接分享,不过这种分享有点不太友好,实用性也不强. 当然,你可以自定义分享内容,包括标题,简介,图片及分享的小程序页面路径. 再高级一点 ...
- [剑指Offer]52-两个链表的第一个公共节点
题目链接 https://www.nowcoder.com/practice/6ab1d9a29e88450685099d45c9e31e46?tpId=13&tqId=11189&t ...
- Django1.0和2.0中的rest_framework的序列化组件之超链接字段的处理
大家看到这个标题是不是有点懵逼,其实我就是想要一个这样的效果 比如我get一条书籍的数据,在一对多的字段中我们显示一个url,看起来是不是很绚! 下面我们就来实现这么一个东西 首先我们一对多字段中的一 ...
- XML 解析技术
xml 解析方式有两种: dom 解析和 sax 解析: 针对着两种解析方式,有三种解析器: sun公司的 jaxp dom4j 组织的 dom4j jdom 组织的 jdom dom 解析XML : ...
- ARM交叉编译工具链
交叉编译工具链是一个由编译器.连接器和解释器组成的综合开发环境,交叉编译工具链主要由binutils.gcc和glibc三个部分组成. 免费版目前有三大主流工具商提供,第一是GNU(提供源码,自行编译 ...
- Windows下adobe Reader中pdf字体helvetica被替换为ArialMT
笔者最近java项目中用itext-2.1.7导出pdf,使用了Helvetica,这个字体是内置的字体,本地Adobe Reader版本9.0 导出的文字是img.nur.cn实际效果 查看了pdf ...
- Jenkins构建.net项目
一.环境搭建 1.安装所需软件 Jenkins\JDK\GIT\VS\IIS\nginx(可选) 1.1 安装iis服务: 控制面板—>程序和功能—>启用或关闭windows功能,勾选所有 ...