-
Notifications
You must be signed in to change notification settings - Fork 1
/
图论-离线LCA-模板
136 lines (128 loc) · 2.04 KB
/
图论-离线LCA-模板
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include<bits/stdc++.h>
#define per(i,a,b) for(int i = (a);i <= (b);++i)
#define rep(i,a,b) for(int i = (b);i >= (b);--i)
using namespace std;
const int maxn = 2e5 + 10;
vector<int> g[maxn+10],query[maxn+10];
map<pair<int,int>,int> cf;
int n = 0,q = 0;
bool vis[maxn];
int fa[maxn],rak[maxn],in[maxn];
vector<pair<int,int> > p;
void init(){
memset(vis,false,sizeof(vis));
memset(rak,0,sizeof(rak));
memset(in,0,sizeof(in));
per(i,1,n){
fa[i] = i;
}
cf.clear();p.clear();
per(i,1,n){
g[i].clear();
query[i].clear();
}
}
int find(int x){
if(fa[x] == x){
return x;
}else{
//return fa[x] = find(fa[x]);//这里不能压缩路径
return find(fa[x]);
}
}
void unite(int x,int y){
x = find(x); y = find(y);
if(x == y){
return ;
}else{
if(rak[x] == rak[y]){
++rak[x];
}
fa[y] = x;
}
}
/*
伪代码:
Tarjan(u)//marge和find为并查集合并函数和查找函数
{
for each(u,v) //访问所有u子节点v
{
Tarjan(v); //继续往下遍历
marge(u,v); //合并v到u上
标记v被访问过;
}
for each(u,e) //访问所有和u有询问关系的e
{
如果e被访问过;
u,e的最近公共祖先为find(e);
}
}
*/
void Tarjan(int u){
int si = g[u].size();
per(i,0,si-1){
int v = g[u][i];
Tarjan(v);
unite(u,v);//
vis[v] = true;
}
int size = query[u].size();
per(i,0,size-1){
int v = query[u][i];
if(vis[v]){
cf[make_pair(u,v)] = cf[make_pair(v,u)] = find(v);
}
}
}
int main(){
while(~scanf("%d",&n)){
init();
per(i,1,n-1){
int x = 0,y = 0;
scanf("%d %d",&x,&y);
g[x].push_back(y);
++in[y];
}
scanf("%d",&q);
per(i,1,q){
int x = 0,y = 0;
scanf("%d %d",&x,&y);
query[x].push_back(y); query[y].push_back(x);
p.push_back(make_pair(x,y));
}
per(i,1,n){
if(in[i] == 0){
//printf("jiji %d\n",i);
Tarjan(i);
}
}
int size = p.size();
printf("%d\n",size);
per(i,0,size-1){
printf("%d\n",cf[p[i]]);
}
}
return 0;
}
/*
9
1 2
1 3
2 4
2 5
5 7
5 8
7 9
3 6
4
9 8
4 6
5 7
5 3
answer:
4
5
1
5
1
*/