题目链接
题意:给你一颗树和一些限制,让你构造每个边的边权满足 限制。
限制: a−>b的最短路径上的最小边权等于 c.
思路:把所有限制按照c从大到小排序,然后依次遍历所有限制,对每条路径上没有赋值的赋值成当前的c。如果都有值且值都大于c,那显然无解。
细节见代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
#define fi first
#define se second
#define pb push_back
int n,m;
vector<int>v[N];
int ans[N];
struct uzi{
int a,b,c;
bool operator <(const uzi & t)const{
return c>t.c;
}
}p[N];
int pr[N];
int ed[5001][5001];
int dfs(int now,int d,int pre){
pr[now]=pre;
if(now==d){
return 1;
}
// cout<<now<<' '<<pre<<endl;
for(auto k:v[now]){
if(k==pre)
continue;
if(dfs(k,d,now))return 1;
}
return 0;
}
int main() {
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<n;i++){
int s,t;
cin>>s>>t;
ed[s][t]=ed[t][s]=i;
v[s].pb(t);
v[t].pb(s);
ans[i]=0;
}
cin>>m;
for(int i=1;i<=m;i++){
int l,r,w;
cin>>l>>r>>w;
p[i]={l,r,w};
}
sort(p+1,p+1+m);
for(int i=1;i<=m;i++){
dfs(p[i].a,p[i].b,0);
int sta=0;
while(pr[p[i].b]){
int x=p[i].b,y=pr[p[i].b];
x=ed[x][y];
if(ans[x]<=p[i].c){
sta=1;
}
ans[x]=max(ans[x],p[i].c);
p[i].b=pr[p[i].b];
}
if(!sta)return cout<<-1,0;
}
for(int i=1;i<n;i++){
if(!ans[i])ans[i]=1e6;
cout<<ans[i]<< ' ';
}
return 0;
}