# |
Submission time |
Handle |
Problem |
Language |
Result |
Execution time |
Memory |
540780 |
2022-03-21T17:25:52 Z |
Olympia |
Valley (BOI19_valley) |
C++17 |
|
709 ms |
70616 KB |
#include <vector>
#include <algorithm>
#include <iostream>
#include <set>
#include <cmath>
#include <map>
#include <random>
#include <cassert>
#include <ctime>
#include <cstdlib>
#include <queue>
#include <limits.h>
using namespace std;
class Tree {
private:
int root;
vector<vector<pair<int64_t,int64_t>>> adj; //node, weight
vector<int64_t> parent;
vector<int64_t> depth;
map<pair<int64_t,int64_t>,int64_t> weight;
vector<bool> isVillage;
vector<int64_t> sub, pre, post;
vector<vector<int>> jmp, dp;
public:
Tree (int64_t N, int64_t root) {
adj.resize(N);
this->root = root;
parent.resize(N);
depth.resize(N);
isVillage.assign(N, false);
sub.resize(N);
pre.resize(N), post.resize(N);
}
void add_edge (int64_t u, int64_t v, int64_t w) {
adj[u].push_back({v, w});
adj[v].push_back({u, w});
weight[{u, v}] = weight[{v, u}] = w;
}
void update_village (int u) {
isVillage[u] = true;
}
int64_t cntr = 0;
void dfs (int64_t curNode, int64_t prevNode) {
parent[curNode] = prevNode;
sub[curNode] = -1;
pre[curNode] = cntr++;
if (curNode == root) {
depth[curNode] = 0;
} else {
depth[curNode] = depth[prevNode] + weight[{curNode, prevNode}];
}
for (pair<int64_t,int64_t> p: adj[curNode]) {
if (p.first != prevNode) {
dfs(p.first, curNode);
if (sub[p.first] != -1) {
sub[curNode] = chmin(sub[p.first] + weight[{curNode, p.first}], sub[curNode]);
}
}
}
if (isVillage[curNode]) {
sub[curNode] = 0;
}
post[curNode] = cntr++;
}
bool isAncestor (int64_t a, int64_t b) {
//is a an ancestor of b?
return (pre[a] <= pre[b] && post[a] >= post[b]);
}
int64_t chmin (int64_t a, int64_t b) {
if (a == -1) return b;
if (b == -1) return a;
return min(a, b);
}
int64_t query (int64_t a1, int64_t a2, int64_t b) {
if (parent[a1] != a2) {
swap(a1, a2);
}
if (!isAncestor(a1, b)) {
return -1;
}
int64_t x = b;
int64_t ans = -1;
for (int i = 31; i >= 0; i--) {
if (isAncestor(a1, jmp[x][i])) {
if (dp[x][i] != -1) {
ans = chmin(ans, dp[x][i] + abs(depth[x] - depth[b]));
}
x = jmp[x][i];
}
}
if (sub[a1] != -1) {
ans = chmin(ans, sub[a1] + abs(depth[b] - depth[a1]));
}
if (ans == -1) {
return LLONG_MAX;
}
return ans;
}
void read () {
dfs(root, -1);
jmp.resize(adj.size());
dp.resize(adj.size());
for (int i = 0; i < adj.size(); i++) {
jmp[i].resize(32);
dp[i].resize(32);
jmp[i][0] = parent[i];
}
jmp[root][0] = root;
for (int j = 1; j < 32; j++) {
for (int i = 0; i < adj.size(); i++) {
jmp[i][j] = jmp[jmp[i][j - 1]][j - 1];
}
}
for (int j = 0; j < 32; j++) {
for (int i = 0; i < adj.size(); i++) {
if (j == 0) {
dp[i][j] = sub[i];
if (sub[jmp[i][0]] != -1) {
dp[i][j] = chmin(dp[i][j], sub[jmp[i][0]] + weight[{jmp[i][0], i}]);
}
dp[root][0] = sub[root];
} else {
dp[i][j] = dp[i][j - 1];
if (dp[jmp[i][j - 1]][j - 1] != -1) {
dp[i][j] = chmin(dp[i][j], dp[jmp[i][j - 1]][j - 1] + abs(depth[jmp[i][j - 1]] - depth[i]));
}
}
}
}
}
};
int main() {
//freopen("inp.txt", "r", stdin);
//freopen("seating.in", "w", stdout);
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int N, S, Q, E;
cin >> N >> S >> Q >> E;
E--;
Tree myTree(N, E);
vector<pair<int64_t,int64_t>> edges;
for (int i = 0; i < N - 1; i++) {
int64_t u, v, w;
cin >> u >> v >> w;
u--, v--;
edges.emplace_back(u, v);
myTree.add_edge(u, v, w);
}
while (S--) {
int64_t x; cin >> x; x--;
myTree.update_village(x);
}
myTree.read();
while (Q--) {
int64_t u, v;
cin >> u >> v;
u--, v--;
int64_t x = myTree.query(edges[u].first, edges[u].second, v);
if (x == -1) {
cout << "escaped\n";
} else if (x == LLONG_MAX) {
cout << "oo\n";
} else {
cout << x << '\n';
}
}
}
Compilation message
valley.cpp: In member function 'void Tree::read()':
valley.cpp:103:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::vector<std::pair<long int, long int> > >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
103 | for (int i = 0; i < adj.size(); i++) {
| ~~^~~~~~~~~~~~
valley.cpp:110:31: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::vector<std::pair<long int, long int> > >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
110 | for (int i = 0; i < adj.size(); i++) {
| ~~^~~~~~~~~~~~
valley.cpp:115:31: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::vector<std::pair<long int, long int> > >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
115 | for (int i = 0; i < adj.size(); i++) {
| ~~^~~~~~~~~~~~
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
2 ms |
340 KB |
Output is correct |
2 |
Incorrect |
3 ms |
460 KB |
Output isn't correct |
3 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
2 ms |
340 KB |
Output is correct |
2 |
Incorrect |
3 ms |
460 KB |
Output isn't correct |
3 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
548 ms |
59260 KB |
Output is correct |
2 |
Correct |
625 ms |
59256 KB |
Output is correct |
3 |
Correct |
565 ms |
59400 KB |
Output is correct |
4 |
Correct |
605 ms |
63700 KB |
Output is correct |
5 |
Correct |
576 ms |
66748 KB |
Output is correct |
6 |
Correct |
709 ms |
70616 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
2 ms |
340 KB |
Output is correct |
2 |
Incorrect |
3 ms |
460 KB |
Output isn't correct |
3 |
Halted |
0 ms |
0 KB |
- |