-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathevolution.cpp
106 lines (89 loc) · 2.02 KB
/
evolution.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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include <iostream>
#include <vector>
#include <map>
#include <string>
using namespace std;
struct query {
int id;
int b;
};
vector<int> age;
vector<vector<int>> children;
vector<vector<query>> queries;
vector<int> answer;
vector<int> path;
// Binary search over the current path to find largest element that is at most maxAge old
int search(int maxAge) {
int a = 0;
int b = path.size() - 1;
while (a != b) {
int m = (a + b) / 2;
if (age[path[m]] <= maxAge) {
b = m;
} else {
a = m + 1;
}
}
return path[a];
}
// Use DFS to compute the path for the current vertex
// Answer all queries for the current vertex by calling the search function
void dfs(int u) {
path.push_back(u);
// Compute answers for queries at u
for (query q : queries[u]) {
answer[q.id] = search(q.b);
}
// Recursion
for (int v : children[u]) {
dfs(v);
}
path.pop_back();
}
// Strategy: Use binary search to answer queries
void solve() {
int n, q;
cin >> n >> q;
// We will be working with integer indices
map<string, int> id; // From name to id
vector<string> name(n); // From id to name
// Read vertices
age = vector<int>(n);
for (int i = 0; i < n; ++i) {
cin >> name[i];
cin >> age[i];
id[name[i]] = i;
}
// Read edges
string parent, child;
children = vector<vector<int>>(n);
for (int i = 0; i < n - 1; ++i) {
cin >> child >> parent;
children[id[parent]].push_back(id[child]);
}
// Read queries
string queryName;
int maxAge;
queries = vector<vector<query>>(n);
for (int queryId = 0; queryId < q; ++queryId) {
cin >> queryName >> maxAge;
queries[id[queryName]].push_back({queryId, maxAge});
}
// Call dfs, the dfs actually solves the problem
answer = vector<int>(n);
path = vector<int>();
dfs(id["luca"]);
// Output answers
for (int j = 0; j < q; ++j) {
cout << name[answer[j]] << " ";
}
cout << endl;
}
int main() {
ios_base::sync_with_stdio(false);
int t; cin >> t;
while (t--) {
solve();
}
return 0;
}