#include <bits/stdc++.h>
using namespace std;
const int MAXN = 200005;
vector<pair<int,int>> adj[MAXN];
int n, q;
int parent[20][MAXN], depth[MAXN];
int parEdge[MAXN];
int edgeValue[MAXN];
int upEdge[20][MAXN];
void dfs(int u, int p, int pedge, int d){
parent[0][u] = p;
depth[u] = d;
parEdge[u] = pedge;
for(auto &e: adj[u]){
int v=e.first, id=e.second;
if(v==p) continue;
dfs(v, u, id, d+1);
}
}
int lca(int a,int b){
if(depth[a] < depth[b]) swap(a,b);
int diff = depth[a] - depth[b];
for(int i=0;i<20;i++)
if(diff & (1<<i)) a = parent[i][a];
if(a==b) return a;
for(int i=19;i>=0;i--)
if(parent[i][a] != parent[i][b]){
a = parent[i][a];
b = parent[i][b];
}
return parent[0][a];
}
void assign_on_path(int u, int anc, int val, bool isMin){
// isMin = true => all edges >= val
// isMin = false => all edges <= val
while(u != anc){
int id = parEdge[u];
if(isMin) edgeValue[id] = max(edgeValue[id], val);
else edgeValue[id] = min(edgeValue[id], val);
u = parent[0][u];
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n;
for(int i=0;i<n-1;i++){
int u,v;
cin >> u >> v;
adj[u].push_back({v,i});
adj[v].push_back({u,i});
edgeValue[i] = 0; // initial = 0
}
dfs(1,0,-1,0);
for(int i=1;i<20;i++)
for(int u=1;u<=n;u++)
parent[i][u] = parent[i-1][ parent[i-1][u] ];
cin >> q;
struct Q { bool isMin; int u,v,z; };
vector<Q> queries;
while(q--){
char c;
int u,v,z;
cin >> c >> u >> v >> z;
queries.push_back({c=='m', u, v, z});
}
// sort queries by z increasing
sort(queries.begin(), queries.end(), [](auto &a, auto &b){
return a.z < b.z;
});
// Apply constraints
for(auto &qr : queries){
int u=qr.u, v=qr.v, z=qr.z;
int w = lca(u,v);
if(qr.isMin){
// path must have all edges >= z
assign_on_path(u, w, z, true);
assign_on_path(v, w, z, true);
} else {
// path must have all edges <= z
if(edgeValue[ parEdge[w] ]); // ignore
assign_on_path(u, w, z, false);
assign_on_path(v, w, z, false);
}
}
// Second pass: ensure at least one edge equals z for each query
for(auto &qr: queries){
int u=qr.u, v=qr.v, z=qr.z;
int w=lca(u,v);
bool placed=false;
// Try path u -> w
int x=u;
while(x!=w){
int id=parEdge[x];
if(edgeValue[id]==z){ placed=true; break; }
x = parent[0][x];
}
// Try path v -> w
x=v;
while(!placed && x!=w){
int id=parEdge[x];
if(edgeValue[id]==z){ placed=true; break; }
x = parent[0][x];
}
if(!placed){
// assign the first edge on the u→w path
x=u;
if(x!=w){
int id = parEdge[x];
edgeValue[id] = z;
continue;
}
// otherwise assign first edge on v→w
x=v;
int id = parEdge[x];
edgeValue[id] = z;
}
}
// Output
for(int u=1;u<=n;u++){
for(auto &e: adj[u]){
int v=e.first, id=e.second;
if(u < v){
cout << u << " " << v << " " << edgeValue[id] << "\n";
}
}
}
return 0;
}
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |