#include <bits/stdc++.h>
using namespace std;
using LL = long long;
const int NAX = 2e5 + 5;
vector<pair<int,int>> edges[NAX];
struct Query {
long long a, b, c;
bool answer = false;
void read() {
cin >> a >> b >> c;
}
void consider(LL x) {
if (x >= a + b + c) {
answer = true;
}
}
void consider(LL x, LL y) {
if (x >= a && y >= b + c) answer = true;
if (x >= b && y >= a + c) answer = true;
if (x >= c && y >= a + b) answer = true;
if (y >= a && x >= b + c) answer = true;
if (y >= b && x >= a + c) answer = true;
if (y >= c && x >= a + b) answer = true;
}
void consider(LL x, LL y, LL z) {
if (x >= a && y >= b && z >= c) answer = true;
if (x >= a && y >= c && z >= b) answer = true;
if (x >= b && y >= a && z >= c) answer = true;
if (x >= b && y >= c && z >= a) answer = true;
if (x >= c && y >= a && z >= b) answer = true;
if (x >= c && y >= b && z >= a) answer = true;
}
};
map<pair<int,int>, pair<long long, long long>> map_dp;
pair<long long, long long> dp_dfs(int a, int b, int c) {
if ((int) edges[b].size() == 1) {
return {c, c};
}
auto it = map_dp.find({a,b});
if (it != map_dp.end()) {
return it->second;
}
long long one = c;
long long two = c;
long long max1 = 0, max2 = 0;
for (pair<int,int> tmp : edges[b]) {
if (tmp.first == a) {
continue;
}
pair<long long, long long> p = dp_dfs(b, tmp.first, tmp.second);
one = max(one, c + p.first);
two = max(two, p.second);
if (p.first > max1) {
max2 = max1;
max1 = p.first;
}
else {
max2 = max(max2, p.first);
}
}
two = max(two, one);
two = max(two, max1 + max2);
return map_dp[{a,b}] = {one, two};
}
struct Full {
int b, c;
long long one, two;
};
vector<Full> fulls[NAX];
vector<Query> queries;
void consider(LL a) {
for (Query& query : queries) {
query.consider(a);
}
}
void consider(LL a, LL b) {
for (Query& query : queries) {
query.consider(a, b);
}
}
void consider(LL a, LL b, LL c) {
for (Query& query : queries) {
query.consider(a, b, c);
}
}
void maxi(pair<LL,LL>& p, LL x) {
if (x > p.first) {
p = {x, p.first};
}
else if (x > p.second) {
p.second = x;
}
}
LL bestTwo(int a, int par1, int par2, bool allowOnes = false) {
LL two = 0;
for (const Full& full : fulls[a]) {
if (full.b != par1 && full.b != par2) {
two = max(two, full.two);
if (allowOnes) {
for (const Full& f2 : fulls[a]) {
if (f2.b != par1 && f2.b != par2 && f2.b != full.b) {
two = max(two, full.one + f2.one);
}
}
}
}
}
return two;
}
void dfs(int a, int par, long long so_far, pair<LL,LL> mx) {
consider(so_far);
consider(so_far, mx.first);
consider(so_far, mx.first, mx.second);
auto here = mx;
maxi(here, bestTwo(a, par, -1, true));
consider(so_far, here.first, here.second);
// if (a == 2 && par == 1 && so_far == 25) {
// cout << bestTwo(1, 2, -1) << endl;
// cout << mx.first << " " << mx.second << endl;
// }
for (const Full& full : fulls[a]) {
if (full.b == par) {
continue;
}
auto nw = mx;
LL his = bestTwo(a, par, full.b, (par == -1));
maxi(nw, his);
dfs(full.b, a, so_far + full.c, nw);
}
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
int n, q;
cin >> n >> q;
for (int i = 0; i < n - 1; i++) {
int a, b, c;
cin >> a >> b >> c;
edges[a].emplace_back(b, c);
edges[b].emplace_back(a, c);
}
queries.resize(q);
for (Query& query : queries) {
query.read();
}
for (int a = 1; a <= n; a++) {
for (auto p : edges[a]) {
pair<long long, long long> x = dp_dfs(a, p.first, p.second);
fulls[a].push_back(Full{p.first, p.second, x.first, x.second});
}
}
for (int a = 1; a <= n; a++) {
// middle node of 3 paths
int k = (int) fulls[a].size();
for (int i = 0; i < k; i++) {
for (int j = i + 1; j < k; j++) {
consider(fulls[a][i].two, fulls[a][j].two);
long long two = fulls[a][i].one + fulls[a][j].one;
pair<long long, long long> mx{0, 0};
for (int z = 0; z < k; z++) {
if (z != i && z != j) {
consider(two, fulls[a][z].two);
maxi(mx, fulls[a][z].two);
}
}
consider(two, mx.first, mx.second);
}
}
}
for (int a = 1; a <= n; a++) {
dfs(a, -1, 0, {0LL,0LL});
}
for (Query query : queries) {
cout << (query.answer ? "TAK" : "NIE") << "\n";
}
}
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 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | #include <bits/stdc++.h> using namespace std; using LL = long long; const int NAX = 2e5 + 5; vector<pair<int,int>> edges[NAX]; struct Query { long long a, b, c; bool answer = false; void read() { cin >> a >> b >> c; } void consider(LL x) { if (x >= a + b + c) { answer = true; } } void consider(LL x, LL y) { if (x >= a && y >= b + c) answer = true; if (x >= b && y >= a + c) answer = true; if (x >= c && y >= a + b) answer = true; if (y >= a && x >= b + c) answer = true; if (y >= b && x >= a + c) answer = true; if (y >= c && x >= a + b) answer = true; } void consider(LL x, LL y, LL z) { if (x >= a && y >= b && z >= c) answer = true; if (x >= a && y >= c && z >= b) answer = true; if (x >= b && y >= a && z >= c) answer = true; if (x >= b && y >= c && z >= a) answer = true; if (x >= c && y >= a && z >= b) answer = true; if (x >= c && y >= b && z >= a) answer = true; } }; map<pair<int,int>, pair<long long, long long>> map_dp; pair<long long, long long> dp_dfs(int a, int b, int c) { if ((int) edges[b].size() == 1) { return {c, c}; } auto it = map_dp.find({a,b}); if (it != map_dp.end()) { return it->second; } long long one = c; long long two = c; long long max1 = 0, max2 = 0; for (pair<int,int> tmp : edges[b]) { if (tmp.first == a) { continue; } pair<long long, long long> p = dp_dfs(b, tmp.first, tmp.second); one = max(one, c + p.first); two = max(two, p.second); if (p.first > max1) { max2 = max1; max1 = p.first; } else { max2 = max(max2, p.first); } } two = max(two, one); two = max(two, max1 + max2); return map_dp[{a,b}] = {one, two}; } struct Full { int b, c; long long one, two; }; vector<Full> fulls[NAX]; vector<Query> queries; void consider(LL a) { for (Query& query : queries) { query.consider(a); } } void consider(LL a, LL b) { for (Query& query : queries) { query.consider(a, b); } } void consider(LL a, LL b, LL c) { for (Query& query : queries) { query.consider(a, b, c); } } void maxi(pair<LL,LL>& p, LL x) { if (x > p.first) { p = {x, p.first}; } else if (x > p.second) { p.second = x; } } LL bestTwo(int a, int par1, int par2, bool allowOnes = false) { LL two = 0; for (const Full& full : fulls[a]) { if (full.b != par1 && full.b != par2) { two = max(two, full.two); if (allowOnes) { for (const Full& f2 : fulls[a]) { if (f2.b != par1 && f2.b != par2 && f2.b != full.b) { two = max(two, full.one + f2.one); } } } } } return two; } void dfs(int a, int par, long long so_far, pair<LL,LL> mx) { consider(so_far); consider(so_far, mx.first); consider(so_far, mx.first, mx.second); auto here = mx; maxi(here, bestTwo(a, par, -1, true)); consider(so_far, here.first, here.second); // if (a == 2 && par == 1 && so_far == 25) { // cout << bestTwo(1, 2, -1) << endl; // cout << mx.first << " " << mx.second << endl; // } for (const Full& full : fulls[a]) { if (full.b == par) { continue; } auto nw = mx; LL his = bestTwo(a, par, full.b, (par == -1)); maxi(nw, his); dfs(full.b, a, so_far + full.c, nw); } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); int n, q; cin >> n >> q; for (int i = 0; i < n - 1; i++) { int a, b, c; cin >> a >> b >> c; edges[a].emplace_back(b, c); edges[b].emplace_back(a, c); } queries.resize(q); for (Query& query : queries) { query.read(); } for (int a = 1; a <= n; a++) { for (auto p : edges[a]) { pair<long long, long long> x = dp_dfs(a, p.first, p.second); fulls[a].push_back(Full{p.first, p.second, x.first, x.second}); } } for (int a = 1; a <= n; a++) { // middle node of 3 paths int k = (int) fulls[a].size(); for (int i = 0; i < k; i++) { for (int j = i + 1; j < k; j++) { consider(fulls[a][i].two, fulls[a][j].two); long long two = fulls[a][i].one + fulls[a][j].one; pair<long long, long long> mx{0, 0}; for (int z = 0; z < k; z++) { if (z != i && z != j) { consider(two, fulls[a][z].two); maxi(mx, fulls[a][z].two); } } consider(two, mx.first, mx.second); } } } for (int a = 1; a <= n; a++) { dfs(a, -1, 0, {0LL,0LL}); } for (Query query : queries) { cout << (query.answer ? "TAK" : "NIE") << "\n"; } } |
English