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;
 }

原文地址:https://www.cnblogs.com/overrate-wsj/p/12267197.html

时间: 2024-08-30 15:53:26

Codeforces Round #617 (Div. 3)F. Berland Beauty的相关文章

[Codeforces Round #617 (Div. 3)] 题解 A,B,C,D,E1,E2,F

[Codeforces Round #617 (Div. 3)] 题解 A,B,C,D,E1,E2,F 1296A - Array with Odd Sum 思路: 如果一开始数组的sum和是奇数,那么直接YES, 否则:如果存在一个奇数和一个偶数,答案为YES,否则为NO 代码: int n; int a[maxn]; int main() { //freopen("D:\\code\\text\\input.txt","r",stdin); //freopen(

Codeforces Round #617 (Div. 3) 题解

目录 Codeforces Round #617 (Div. 3) 题解 前言 A. Array with Odd Sum 题意 做法 程序 B. Food Buying 题意 做法 程序 C. Yet Another Walking Robot 题意 做法 程序 D. Fight with Monsters 题意 做法 程序 E1. String Coloring (easy version) 题意 做法 程序 E2. String Coloring (hard version) 题意 做法

构造 Codeforces Round #Pi (Div. 2) B. Berland National Library

题目传送门 1 /* 2 题意:给出一系列读者出行的记录,+表示一个读者进入,-表示一个读者离开,可能之前已经有读者在图书馆 3 构造:now记录当前图书馆人数,sz记录最小的容量,in数组标记进去的读者,分情况讨论一下 4 */ 5 /************************************************ 6 * Author :Running_Time 7 * Created Time :2015-8-6 0:23:37 8 * File Name :B.cpp 9

Codeforces Round #486 (Div. 3) F. Rain and Umbrellas

Codeforces Round #486 (Div. 3) F. Rain and Umbrellas 题目连接: http://codeforces.com/group/T0ITBvoeEx/contest/988/problem/E Description Polycarp lives on a coordinate line at the point x=0. He goes to his friend that lives at the point x=a. Polycarp can

Codeforces Round #501 (Div. 3) F. Bracket Substring

题目链接 Codeforces Round #501 (Div. 3) F. Bracket Substring 题解 官方题解 http://codeforces.com/blog/entry/60949 ....看不懂 设dp[i][j][l]表示前i位,左括号-右括号=j,匹配到l了 状态转移,枚举下一个要填的括号,用next数组求状态的l,分别转移 代码 #include<bits/stdc++.h> using namespace std; const int maxn = 207;

Codeforces Round #392 (Div. 2) F. Geometrical Progression

原题地址:http://codeforces.com/contest/758/problem/F F. Geometrical Progression time limit per test 4 seconds memory limit per test 256 megabytes input standard input output standard output For given n, l and r find the number of distinct geometrical pro

Codeforces Round #531 (Div. 3) F. Elongated Matrix(状压DP)

F. Elongated Matrix 题目链接:https://codeforces.com/contest/1102/problem/F 题意: 给出一个n*m的矩阵,现在可以随意交换任意的两行,最后从上到下,从左到右形成一个序列s1,s2.....snm,满足对于任意相邻的两个数,它们差的绝对值的最大值为k. 现在问怎么交换行与行,可以使得最后的这个k最大. 题解: 人生中第一道状压dp~其实还是参考了这篇博客:https://blog.csdn.net/CSDNjiangshan/art

Codeforces Round #548 (Div. 2) F splay(新坑) + 思维

https://codeforces.com/contest/1139/problem/F 题意 有m个人,n道菜,每道菜有\(p_i\),\(s_i\),\(b_i\),每个人有\(inc_j\),\(pref_j\),一个人可以买一道菜的条件是 1. \(p_i \leq inc_j \leq s_i\) 2. \(|b_i - pref_j| \leq inc_j-p_i\) ,问每个人分别能买多少道菜 题解 转化一下公式 \(p_i \leq inc_j \leq s_i\) 下面两个满

Codeforces Round #549 (Div. 2) F 数形结合 + 凸包(新坑)

https://codeforces.com/contest/1143/problem/F 题意 有n条形如\(y=x^2+bx+c\)的抛物线,问有多少条抛物线上方没有其他抛物线的交点 题解 \(y=x^2+bx+c=>y+x^2=bx+c\),转换为点\((x,y+x^2)\)在bx+c的直线上 两个点确定一条抛物线,同时也确定了一条直线 需要选择最上面那些点相邻确定的抛物线,所以维护一个上凸包即可 维护上凸包,当前点在前进方向左边需要向后退,cross(a,b)>=0 代码 #inclu