-
Notifications
You must be signed in to change notification settings - Fork 698
/
Tree Construction with Specific Vertices.cpp
88 lines (81 loc) · 1.55 KB
/
Tree Construction with Specific Vertices.cpp
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
int tim=0;
int parent[LG][N];
int tin[N], tout[N], level[N], vertices[N];
vector<int> g[N], tree[N];
void dfs(int k, int par, int lvl)
{
tin[k]=++tim;
parent[0][k]=par;
level[k]=lvl;
for(auto it:g[k])
{
if(it==par)
continue;
dfs(it, k, lvl+1);
}
tout[k]=tim;
}
void precompute()
{
for(int i=1;i<LG;i++)
for(int j=1;j<=n;j++)
if(parent[i-1][j])
parent[i][j]=parent[i-1][parent[i-1][j]];
}
int LCA(int u, int v)
{
if(level[u]<level[v])
swap(u,v);
int diff=level[u]-level[v];
for(int i=LG-1;i>=0;i--)
{
if((1<<i) & diff)
{
u=parent[i][u];
}
}
if(u==v)
return u;
for(int i=LG-1;i>=0;i--)
{
if(parent[i][u] && parent[i][u]!=parent[i][v])
{
u=parent[i][u];
v=parent[i][v];
}
}
return parent[0][u];
}
bool isancestor(int u, int v) //Check if u is an ancestor of v
{
return (tin[u]<=tin[v]) && (tout[v]<=tout[u]);
}
int work()
{
sort(vertices+1, vertices+k+1, [](int a, int b)
{
return tin[a]<tin[b];
});
int idx=k;
for(int i=1;i<idx;i++)
vertices[++k]=LCA(vertices[i], vertices[i+1]);
sort(vertices+1, vertices+k+1);
k=unique(vertices+1, vertices+k+1) - vertices - 1;
sort(vertices+1, vertices+k+1, [](int a, int b)
{
return tin[a]<tin[b];
});
stack<int> s;
s.push(vertices[1]);
for(int i=2;i<=k;i++)
{
while(!isancestor(s.top(), vertices[i]))
s.pop();
tree[s.top()].push_back(vertices[i]);
s.push(vertices[i]);
}
for(int i=1;i<=k;i++)
tree[vertices[i]].clear();
}
//Problem 1: http://codeforces.com/contest/613/problem/D
//Solution 1: http://codeforces.com/contest/613/submission/40474762