• CodeForce 1296F. Number of Subsequences


    题目链接

    https://codeforces.com/problemset/problem/1296/F

    题意

    给你一颗共有 N 个节点的树,再给你N - 1条边,你不知道这些边的边权,但是你有 M 条信息,每条信息将告诉你从 U 到 V 的所有边中最小值为 W,现要求你构造出这N - 1条边的边权。

    思路

      以节点1为树根建树,我们先对 M 条信息中每条路径上的最小边权W从大到小排序,然后从每个U,V点出发直到到达它们的最近公共祖先,在沿途中若遇到某条边有边权且大于W,则无法构建,否则把该边权设为W。M条信息都操作完后输出答案即可。

    AC代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int INF = 1000000;
    typedef pair<int,int> pii;
    const int maxn = 5500;
    int d[maxn], far[maxn], ans[maxn], val_pre[maxn] , index_pre[maxn];
    vector<pii> G[maxn]; //secon表示这条边是第几条。
    struct node{
        int u, v, w;
        bool operator <(const node & b) const{
            return w > b.w;
        }
    } a[maxn];
    void dfs(int v, int last){
        d[v] = d[last] + 1;
        far[v] = last;
        for(auto u : G[v]){
            if(u.first == last) continue;
            dfs(u.first, v);
            index_pre[u.first] = u.second;
        }
    }
    bool check(int u, int v, int w){
        int mi = INF;
        if(d[u] < d[v]) swap(u, v);
        while(d[u] != d[v]) // 先把深度大的走到同一深度
        {
            if(val_pre[u] == INF)
            val_pre[u] = w;
            mi = min(mi, val_pre[u]);
            u = far[u];
        }
        while(u != v)//再走到同一节点
        {
            if(val_pre[u] == INF) val_pre[u] = w;
            mi = min(val_pre[u] , mi);
            u = far[u];
            if(val_pre[v] == INF) val_pre[v] = w;
            mi = min(val_pre[v] , mi);
            v = far[v];
        }
        return mi == w;
    }
    int main()
    {
        std::ios::sync_with_stdio(false);
        int n, m;
        cin >> n;
        for(int i = 1;i <= n;i++) val_pre[i] = INF;
        for(int i = 1;i <= n - 1;i++)
        {
            int u, v;
            cin >> u >> v;
            G[v].push_back({u,i});
            G[u].push_back({v,i});
        }
        dfs(1, 0);
        cin >> m;
        for(int i = 1;i <= m;i++) cin >> a[i].u >> a[i].v >> a[i].w;
        sort(a + 1, a + m + 1);
        for(int i = 1;i <= m;i++)
        {
            if(!check(a[i].u, a[i].v, a[i].w)){
                cout << -1 << endl;
                return 0;
            }
        }
        for(int i = 2;i <= n;i++){
            ans[index_pre[i]] = val_pre[i];
        }
        for(int i = 1;i < n;i++) cout << ans[i] << " ";
        return 0;
    }
    
  • 相关阅读:
    SQLSERVER查询数据库文件大小
    SQLSERVER 检查内容
    20万DBA都在关注的12个问题 [转载]
    oswbb工具分析主机性能
    Suspending MMON slave action kewrmapsa_ for 82800 seconds
    一次direct path read 故障处理
    Auto Optimizer Stats Collection in 12c
    ORACLE 动态注册和静态注册的区别(转)
    记一次cursor pin s wait on X的处理
    树莓派3b的raspberrypi系统安装pip
  • 原文地址:https://www.cnblogs.com/Carered/p/13763105.html
Copyright © 2020-2023  润新知