zoukankan      html  css  js  c++  java
  • [CF1296F] Berland Beauty

    Description

    树上每条边有一个权值 (x_i) 未知,给定 (m) 个限制每个限制描述了路径 (p,q) 上的最小值,构造权值方案或者判定无解。

    Solution

    贪心,对于每个限制,路径上所有点暴力取 max 即可。最后再扫一遍检查是否所有条件都被满足。

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 1000005;
    
    int n, m, t1, t2, t3, t4;
    int a[N], b[N], c[N], d[N];
    vector<int> g[N];
    int ans[N];
    int vis[N];
    vector<int> vec;
    int target;
    vector<pair<int, int>> edges;
    
    void dfs0(int p)
    {
        vis[p] = 1;
        for (int q : g[p])
        {
            if (vis[q] == 0)
            {
                d[q] = d[p] + 1;
                dfs0(q);
            }
        }
    }
    
    void update(int p, int q, int val)
    {
        // cout << "upd " << p << " " << q << " = " << val << endl;
        int x = d[p] < d[q] ? q : p;
        // cout << " x=" << x << endl;
        ans[x] = max(ans[x], val);
    }
    
    int query(int p, int q)
    {
        int x = d[p] < d[q] ? q : p;
        return ans[x];
    }
    
    bool dfs(int p)
    {
        vis[p] = 1;
        vec.push_back(p);
        if (p == target)
        {
            return true;
        }
        for (int q : g[p])
        {
            if (vis[q] == 0)
            {
                if (dfs(q))
                    return true;
            }
        }
        if (vec.size())
            vec.pop_back();
        return false;
    }
    
    void solve(int p, int q, int val)
    {
        memset(vis, 0, sizeof vis);
        vec.clear();
        target = q;
        dfs(p);
        for (int i = 1; i < vec.size(); i++)
        {
            int x = vec[i - 1], y = vec[i];
            update(x, y, val);
        }
    }
    
    bool check(int p, int q, int val)
    {
        memset(vis, 0, sizeof vis);
        vec.clear();
        target = q;
        dfs(p);
        for (int i = 1; i < vec.size(); i++)
        {
            int x = vec[i - 1], y = vec[i];
            if (query(x, y) == val)
                return true;
        }
        return false;
    }
    
    signed main()
    {
        ios::sync_with_stdio(false);
    
        cin >> n;
        for (int i = 1; i < n; i++)
        {
            cin >> t1 >> t2;
            g[t1].push_back(t2);
            g[t2].push_back(t1);
            edges.push_back({t1, t2});
        }
    
        dfs0(1);
    
        for (int i = 1; i <= n; i++)
            ans[i] = 1;
    
        cin >> m;
        for (int i = 1; i <= m; i++)
        {
            cin >> a[i] >> b[i] >> c[i];
        }
    
        for (int i = 1; i <= m; i++)
        {
            solve(a[i], b[i], c[i]);
        }
    
        int flag = 1;
        for (int i = 1; i <= m; i++)
        {
            if (check(a[i], b[i], c[i]) == 0)
            {
                cout << -1;
                return 0;
            }
        }
    
        for (auto edge : edges)
        {
            int u = edge.first, v = edge.second;
            cout << query(u, v) << " ";
        }
    }
    
  • 相关阅读:
    TCP四次握手断开连接(十一)
    Go-函数
    Go-数据类型以及变量,常量
    GO语言介绍以及开发环境配置
    Socket与WebSocket以及http与https重新总结
    希尔排序
    第19课
    第18课
    外传篇3 动态内存申请的结果
    外传篇2 函数的异常规格说明
  • 原文地址:https://www.cnblogs.com/mollnn/p/14030449.html
Copyright © 2011-2022 走看看