zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    使用UFW防火墙拦截特定IP地址
    利用iptables防止syn flood攻击
    DDOS攻击模拟复现
    服务器遭到SYN攻击怎么办?如何防御SYN攻击?
    iptables限制同一IP连接数
    TIME_WAIT和CLOSE_WAIT状态区别
    详解TIME_WAIT过多,引起的请求502的问题。
    TIME_WAIT太多解决思路和方法
    黑客是如何攻击 WebSockets 和 Socket.io的
    免费CDN加速CloudFlare申请教程及使用 提供免费加速和防DDOS攻击
  • 原文地址:https://www.cnblogs.com/Carered/p/13763105.html
Copyright © 2011-2022 走看看