https://www.luogu.com.cn/problem/P4374
洛谷这题一言难尽
添加新边影响的边只有与新边成环的所有边,那就很简单了,树链剖分树上最大值就行了。。。很简单不知道为啥是紫题
#include<iostream>
#include<vector>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;
const int maxn = 2e5+11;
const int INF = 1e9+111;
vector<int>G[maxn];
void add(int be,int en){
G[be].push_back(en);
}
int n,m;
int top[maxn],id[maxn],cnt,dep[maxn],fa[maxn],siz[maxn],son[maxn];
int dfs(int x,int f,int d) {
fa[x] = f;
dep[x] = d;
siz[x] = 1;
int s = 0;
for(int i=0; i< G[x].size(); i++) {
int p = G[x][i];
if(p == f) continue;
dfs(p,x,d+1);
siz[x] += siz[p];
if(s < siz[p]) {
s = siz[p];
son[x] = p;
}
}
return 0;
}
int dfs2(int x,int t) {
id[x] = ++cnt;
top[x] = t;
if(son[x] != 0) dfs2(son[x],t);
for(int i=0; i<G[x].size(); i++) {
int p =G[x][i];
if(p == son[x] || p == fa[x]) continue;
dfs2(p,p);
}
return 0;
}
//建立线段树
struct Node {
int ans,lazy;
} tree[maxn*4];
int bulit(int node,int be,int en) {
int mid =be+en>>1;
int l = node*2;
int r = node*2+1;
if(be == en) {
tree[node].ans = INF;
tree[node].lazy = INF;
return 0;
}
tree[node].ans = INF;
tree[node].lazy = INF;
bulit(l,be,mid);
bulit(r,mid+1,en);
return 0;
}
int push(int node,int be,int en) {
int mid = be +en >>1;
int l = node*2;
int r = node*2+1;
if(tree[node].lazy != INF) {
tree[l].ans = min(tree[l].ans , tree[node].lazy);
tree[r].ans = min(tree[r].ans , tree[node].lazy);
tree[l].lazy = min(tree[node].lazy,tree[l].lazy);
tree[r].lazy = min(tree[node].lazy,tree[r].lazy);
tree[node].lazy = INF;
}
return 0;
}
int update(int node,int be,int en,int LL,int RR,int val) {
if(LL > RR) return 0;
int mid = be +en >>1;
int l = node*2;
int r = node*2+1;
if(LL <= be && en <= RR) {
tree[node].ans = min(tree[node].ans ,val);
if(tree[node].lazy != 0) tree[node].lazy = min(tree[node].lazy,val);
return 0;
}
push(node,be,en);
if(LL <= mid) update(l,be,mid,LL,RR,val);
if(RR > mid) update(r,mid+1,en,LL,RR,val);
tree[node].ans = min(tree[l].ans,tree[r].ans);
return 0;
}
int ask(int node,int be,int en,int LL,int RR) {
if(LL > RR) return INF;
int mid = be + en >> 1;
int l = node*2;
int r = node*2+1;
if(LL <= be && en <= RR) {
return tree[node].ans;
}
int a = INF,b = INF;
push(node,be,en);
if(LL <= mid) a = ask(l,be,mid,LL,RR);
if(RR > mid) b = ask(r,mid+1,en,LL,RR);
return min(a,b);
}
int change(int x,int y,int val) {
int ans = INF;
while(top[x] != top[y]) {
if(dep[top[x]] < dep[top[y]]) swap(x,y);
update(1,1,n,id[top[x]],id[x],val);
x = fa[top[x]];
}
if(dep[x] > dep[y]) swap(x,y);
update(1,1,n,id[x] + 1,id[y],val);
return 0;
}
vector<pair<int,int> >ins;
vector<int>ans;
int main() {
// freopen("in.in","r",stdin);
// freopen("out.out","w",stdout);
scanf("%d %d",&n,&m);
for(int i=1; i<n; i++) {
int be,en;
scanf("%d%d",&be,&en);
ins.push_back(make_pair(be,en));
add(be,en);
add(en,be);
}
dfs(1,-1,1);
dfs2(1,1);
bulit(1,1,n);
while(m--) {
int x,y,w;
scanf("%d %d %d",&x,&y,&w);
change(x,y,w);
}
for(int i=0;i<ins.size();i++){
int x = ins[i].first;
int y = ins[i].second;
if(dep[x] < dep[y]) swap(x,y);
int a = ask(1,1,n,id[x],id[x]);
ans.push_back(a);
}
for(int i=0;i<ans.size();i++){
if(ans[i] == INF) ans[i] = -1;
printf("%d
",ans[i]);
}
return 0;
}