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;
}
原文地址:https://www.cnblogs.com/Carered/p/13763105.html