codedorces 1296F Berland Beauty dfs+暴力

https://vjudge.net/problem/CodeForces-1296F
在这里插入图片描述
在这里插入图片描述
题目大意:给出一棵有 n n 个节点的无根树,对于 m m 个询问 ( u i , v i , d i ) (u_i,v_i,d_i) 满足从 u i u_i v i v_i 的路径上的边权的最小值是 d i d_i ,如果可以满足的话输出 n 1 n-1 条边的权值,要求 1 < = f i < = 1 0 6 1<=f_i<=10^6 ,否则输出 1 -1

思路:虽然是 F F 题,其实就是一个裸的暴力。依次处理 m m 个询问,找到从 u i u_i v i v_i 的路径,然后把该路径上的边的权值取本身与 d i d_i 的最大值。然后再遍历一遍 m m 个询问,看 u i u_i v i v_i 的路径上的边权的最小值是否等于 d i d_i ,若相等则说明有解,输出每条边的边权即可( 0 0 可以改成范围内的任意一个值)。树上找任意两点的路径也比较简单,这里提供两种方法:(1)暴力,用二维数组 f a [ u ] [ v ] fa[u][v] 表示以 u u 为根时 v v 的父节点,一共需要 n n d f s dfs ,复杂度 O ( n 2 ) O(n^2) ;(2)用 f a [ v ] fa[v] 表示以 1 1 为根时 v v 的父节点,只需 1 1 d f s dfs ,但是求路径时需要求 L C A LCA ,因此复杂度为 O ( n l g n ) O(nlgn) 。以下代码采取第一种方法(懒得写第二种 o r z orz )。总复杂度 O ( n m a x ( n , m ) ) O(n*max(n,m))

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;

const int maxn=5005;

struct Edge
{
    int to,nxt;
}edge[maxn<<1];

int n,m,tot,root;
int head[maxn];
int x[maxn],y[maxn],fa[maxn][maxn],ans[maxn][maxn];
int u[maxn],v[maxn],d[maxn];

inline void addedge(int u,int v)
{
    edge[++tot].to=v,edge[tot].nxt=head[u],head[u]=tot;
}

inline void dfs(int u,int f)
{
    fa[root][u]=f;
    for(int i=head[u],v;i;i=edge[i].nxt)
    {
        v=edge[i].to;
        if(v!=f)
            dfs(v,u);
    }
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<n;i++)
    {
        scanf("%d %d",&x[i],&y[i]);
        addedge(x[i],y[i]),addedge(y[i],x[i]);
    }
    for(int i=1;i<=n;i++)
        root=i,dfs(i,0);
    scanf("%d",&m);
    for(int i=0;i<m;i++)
    {
        scanf("%d %d %d",&u[i],&v[i],&d[i]);
        int a=u[i],b=v[i];
        int fb=fa[a][b];
        while(fb!=a)
        {
            ans[fb][b]=ans[b][fb]=max(ans[fb][b],d[i]);
            b=fb;
            fb=fa[a][fb];
        }
        ans[fb][b]=ans[b][fb]=max(ans[fb][b],d[i]);
    }
    bool flag=1;
    for(int i=0;i<m&&flag;i++)
    {
        int a=u[i],b=v[i];
        int fb=fa[a][b];
        int MIN=INF;
        while(fb!=a)
        {
            MIN=min(ans[fb][b],MIN);
            b=fb;
            fb=fa[a][fb];
        }
        MIN=min(ans[fb][b],MIN);
        if(MIN!=d[i])
            flag=0;
    }
    if(flag)
    {
        for(int i=1;i<n;i++)
        {
            if(!ans[x[i]][y[i]])
                ans[x[i]][y[i]]=1;
            printf("%d ",ans[x[i]][y[i]]);
        }
    }
    else
        printf("-1\n");
    return 0;
}

发布了677 篇原创文章 · 获赞 30 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/xiji333/article/details/104201145