Codeforces Round #617 (Div. 3) F. Berland Beauty

题目链接
题意:给你一颗树和一些限制,让你构造每个边的边权满足 限制。
限制: a > b a->b 的最短路径上的最小边权等于 c 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;
}
发布了158 篇原创文章 · 获赞 81 · 访问量 9646

猜你喜欢

转载自blog.csdn.net/qq_40655981/article/details/104355191