哎 感博客还是要写的 要不每天都在偷懒QAQ 真的会变渣的啊
离线Tarjan算法的实现模板
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int MAXN = 1e5+10;
int f[MAXN], ances[MAXN];
int in[MAXN], vis[MAXN];
vector<int> tree[MAXN];
vector<int> query[MAXN];
int root, n;
int find(int x)
{
return x==f[x]?x:f[x]=find(f[x]);
}
int unite(int x,int y)
{
x= find(x), y = find(y);
if(x != y) f[x] = y;
}
void init()
{
for(int i = 0; i <= n; i++) {
vis[i] = false; tree[i].clear();
query[i].clear(); in[i] = 0;
f[i] = i;
}
}
void input_tree()
{
for(int i = 0; i < n-1; i++) {
int x, y;
scanf("%d%d",&x,&y);
tree[x].push_back(y);
in[y]++;
}
for(int i = 1; i <= n; i++) if(in[i] == 0) root = i;
}
void input_query()
{
int x, y;
scanf("%d%d",&x,&y);
query[x].push_back(y);
query[y].push_back(x);
}
void tarjan(int u)
{
for(int i = 0; i < tree[u].size(); i++) {
int v = tree[u][i];
tarjan(v);
unite(u,v);
ances[find(u)] = u;
}
vis[u] = true;
for(int i = 0; i < query[u].size(); i++) {
int v = query[u][i];
if(vis[v]) printf("%d\n",ances[find(v)]);
}
}
int main()
{
int T;
while(~scanf("%d",&T)) {
while(T--) {
scanf("%d",&n);
init(); input_tree(); input_query();
tarjan(root);
}
}
return 0;
}
在线doubly算法
朴素的算法
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 1e5+10;
vector<int> tree[MAXN];
int root, n;
int in[MAXN];
int par[MAXN], depth[MAXN];
void dfs(int v, int p, int d)
{
par[v] = p;
depth[v] = d;
for(int i = 0; i < tree[v].size(); i++) {
if(tree[v][i] != p) dfs(tree[v][i], v, d+1);
}
}
void init()
{
dfs(root, -1, 0);
}
int lca_pusu(int u,int v)
{
while(depth[u] > depth[v]) u = par[u];
while(depth[v] > depth[u]) v = par[v];
while(u != v) {
u = par[u];
v = par[v];
}
}
void input_tree()
{
for(int i = 0; i < n-1; i++) {
int x, y;
scanf("%d%d",&x,&y);
tree[x].push_back(y);
in[y]++;
}
for(int i = 1; i <= n; i++) if(!in[i]) root = i;
}
void input_query()
{
int x, y;
scanf("%d%d",&x,&y);
printf("%d\n",lca_pusu(x,y));
}
int main()
{
int T;
while(~scanf("%d",&T)) {
while(T--) {
scanf("%d",&n);
for(int i = 0; i <= n; i++) {
tree[i].clear();
in[i] = 0; depth[i] = 0;
par[i] = 0;
}
input_tree();init();
input_query();
}
}
return 0;
}
倍增
这里写代码片
在线RMQ算法