zoukankan      html  css  js  c++  java
  • Codeforces Round #617 (Div. 3)F. Berland Beauty

    题意:

    给一棵树,边权未知,现在给m组约束,每组约束给出从u到v路径中的最小值,现在让你给出一组边权,使得符合之前的约束,不能给出输出-1

    思路:

    因为n较小,对于每组约束我们可以直接暴力修改路径上的权值,如果边的权值小于当前约束的最小值,则将权值修改,最后再根据每组约束暴力走一遍路径看路径是否满足要求,如果不满足则输出-1,最后还得对那些没有修改过的边随意赋值

    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<cstring>
    #define inf 0x3f3f3f3f 
     using namespace std;
     const int maxn=5005;
     int id[maxn][maxn],edge[maxn][maxn],fa[maxn],f[maxn],dep[maxn];
     //id记录从i到j这条边的编号,edge记录边的权值,fa记录i的父亲是谁,f记录边的权值 ,dep记录深度 
     vector<int> a[maxn];
     int from[maxn],to[maxn],mi[maxn];
     int n,m,u,v,w;
     void dfs(int x,int p)//处理出父亲与深度 
     {
         fa[x]=p,dep[x]=dep[p]+1;
        for(int i=0;i<a[x].size();i++)
            if(a[x][i]!=p) dfs(a[x][i],x);
     }
     void dfs2(int x,int p)
     {
         for(int i=0;i<a[x].size();i++){
             if(a[x][i]!=p){
                 int to=a[x][i];
                 f[id[x][to]]=edge[x][to];
                dfs2(a[x][i],x);
             }
         }
     }
     void solve()
     {
         scanf("%d",&m);
         for(int i=1;i<=m;i++){
             scanf("%d%d%d",&from[i],&to[i],&mi[i]);
             if(dep[from[i]]<dep[to[i]])    swap(from[i],to[i]);
            int k1=from[i],k2=to[i],mini=mi[i];
             while(dep[k1]!=dep[k2]){
                 int p=fa[k1];
                 if(edge[p][k1]<=mini) edge[p][k1]=edge[k1][p]=mini;
                 k1=p;
             }
            while(k1!=k2){
                int p1=fa[k1],p2=fa[k2];
                if(edge[p1][k1]<=mini) edge[p1][k1]=edge[k1][p1]=mini;
                if(edge[p2][k2]<=mini) edge[p2][k2]=edge[k2][p2]=mini;
                 k1=p1,k2=p2;
            }
         }
        for(int i=1;i<=m;i++){
            int x=inf;
             int k1=from[i],k2=to[i],mini=mi[i];
             if(dep[k1]<dep[k2])    swap(k1,k2);
             while(dep[k1]!=dep[k2]){
                 int p=fa[k1];
                 x=min(x,edge[p][k1]); 
                 k1=p;
             }
            while(k1!=k2){
                int p1=fa[k1],p2=fa[k2];
                x=min(x,edge[p1][k1]);
                x=min(x,edge[p2][k2]);
                 k1=p1,k2=p2;
            }
            if(x!=mini){ cout<<-1<<endl;return;}
         }
         dfs2(1,0);    
         for(int i=1;i<n;i++){
             if(!f[i])    cout<<100000<<" ";
             else cout<<f[i]<<" ";
         }
     }
     int main()
     {
         scanf("%d",&n);
         for(int i=1;i<n;i++){
             scanf("%d%d",&u,&v);
             a[u].push_back(v);
             a[v].push_back(u);
             id[u][v]=id[v][u]=i;
         }
        dfs(1,0);
        solve(); 
        return 0;
     }
  • 相关阅读:
    JDOJ 2197: 校门外的树
    简单线段树知识点详解
    求GCD(最大公约数)的两种方式
    USACO Buying Feed, II
    USACO Dueling GPS's
    USACO Milking Cows
    NOIP 2014 比例简化
    USACO Clumsy Cows
    JDOJ 1140: 完数
    NOIP 2008 火柴棒等式
  • 原文地址:https://www.cnblogs.com/overrate-wsj/p/12267197.html
Copyright © 2011-2022 走看看