题目链接:Codeforces - Berland Beauty
题目大意:就是给你很多树上点对之间边的min,问是否存在一组合法方案。
所以我们对于两组边有交的条件,只需要取max即可,因为要两个都满足。
因为n很小所以暴力修改即可,如果n比较大我们就需要 树剖+势能线段树 。
最后check一下min即可。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=5e3+10,inf=0x3f3f3f3f;
int n,v[N],f[N],dep[N],a[N],b[N],c[N],m,p[N],q[N];
vector<int> g[N];
inline void add(int a,int b){g[a].push_back(b),g[b].push_back(a);}
void dfs(int x,int fa){
dep[x]=dep[fa]+1; f[x]=fa;
for(auto to:g[x]) if(to!=fa) dfs(to,x);
}
void change(int x,int y,int val){
while(x!=y){
if(dep[x]<dep[y]) swap(x,y);
v[x]=max(v[x],val); x=f[x];
}
}
int get(int x,int y){
int mi=inf;
while(x!=y){
if(dep[x]<dep[y]) swap(x,y);
mi=min(mi,v[x]); x=f[x];
}
return mi;
}
signed main(){
cin>>n;
for(int i=1;i<n;i++) cin>>p[i]>>q[i],add(p[i],q[i]);
dfs(1,1); cin>>m;
for(int i=1;i<=m;i++){
cin>>a[i]>>b[i]>>c[i],change(a[i],b[i],c[i]);
}
for(int i=1;i<=m;i++)
if(get(a[i],b[i])!=c[i]) return puts("-1"),0;
for(int i=1,res;i<n;i++){
if(dep[p[i]]>dep[q[i]]) res=v[p[i]];
else res=v[q[i]];
if(!res) res=1;
cout<<res<<' ';
}
return 0;
}