首先本人是一个嵶苟,向前星还不太熟,所以就用vector………….
1.什么是lca: Lca就是指一棵树中某2个点的最近共同祖先
2.一般有哪些方法? 1.dfs 2.RMQ 3.tarjan 4.倍增法
前2种是属于离线算法,后2种属于在线算法,所谓离线算法就是把要查询的点对全部储存起来,再一次性把所有输出,在打比赛的过程中:
in1
out1
in2
out2
和
in1
in2
out1
out2
这2种格式是一致的,所以我们大可用tarjan求lca
代码:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<string>
#include<string.h>
#include<set>
#include<stdlib.h>
#define INF 0x3f3f3f
using namespace std;
typedef long long LL;
struct node {
int to;
int v;
node(int a, int b)
{
to = a;
v = b;
}
node();
};
struct node2 {
int to;
int lca;
node2(int a)
{
to = a;
lca = 0;
}
};
struct node3 {
int to;
int from;
node3(int a, int b)
{
from = a;
to = b;
}
};
bool vis[10010];
int n, m,k,p[10100],dis[10100];
vector<node>arr[10010];
vector<node2>qarr[10010];
vector<node3>q;
int find(int a)
{
if (p[a] == a)
return a;
else
return p[a] = find(p[a]);
}
void lca(int a)
{
p[a] = a;
vis[a] = 1;
for (int i = 0; i < arr[a].size(); i++)
{
if (!vis[arr[a][i].to])
{
lca(arr[a][i].to);
p[arr[a][i].to] = a;
}
}
for (int i = 0; i < qarr[a].size(); i++)
{
if (vis[qarr[a][i].to])
{
qarr[a][i].lca = find(qarr[a][i].to);
}
}
}
void dfs(int to,int pp,int s)
{
dis[to] = s + dis[pp];
for (int i = 0; i < arr[to].size(); i++)
{
dfs(arr[to][i].to, to, arr[to][i].v);
}
}
int main()
{
char temp;
cin >> n >> m;
for (int i = 1; i <= m; i++)
{
int a, b, c;
cin >> a >> b >> c;
arr[a].push_back(node(b, c));
arr[b].push_back(node(a, c));
}
cin >> k;
for (int i = 1; i <= k; i++)
{
int a, b;
cin >> a >> b;
qarr[a].push_back(node2(b));
qarr[b].push_back(node2(a));
}
lca(1);
for (int i = 1; i <= n; i++)
{
for (int j = 0; j < qarr[i].size(); j++)
{
if (qarr[i][j].lca)
cout << i << ' ' << qarr[i][j].to << ' ' << qarr[i][j].lca << endl;
}
}
return 0;
}