zoukankan      html  css  js  c++  java
  • [CF1338B] Edge Weight Assignment

    Description

    给定一棵 $ n $ 个点的无根树,要求给每条边分配一个正整数权值,使得任意两个叶子节点之间路径上的边权异或值为 $ 0 $。求最少要多少种不同权值,以及最多可以使用多少种不同权值。
    这里,填入的边权值可以为任意大。
    $ 3 le nle 10^5 $

    Solution

    考虑最小值,如果存在两个叶子之间的距离为奇数,则答案为 (3)(没有连接叶节点的边上交替填 (1,2),部分叶子边可能填 (3)),否则答案为 (1)

    考虑最大值,将每个结点的叶子结点合并为一个结点后,计算树边的总数

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    #define dis dep
    const int N = 1000005;
    int n,vis[N],dep[N],f[N],ans;
    vector <int> g[N],leaf;
    
    void dfs1(int p) {
        vis[p]=1;
        for(int q:g[p]) if(vis[q]==0) {
            dep[q]=dep[p]+1;
            if(g[q].size()==1) ++f[p];
            dfs1(q);
        }
        if(f[p]) ans-=f[p]-1;
    }
    
    
    signed main() {
        ios::sync_with_stdio(false);
        cin>>n;
        for(int i=1;i<n;i++) {
            int t1,t2;
            cin>>t1>>t2;
            g[t1].push_back(t2);
            g[t2].push_back(t1);
        }
        int r=0;
        for(int i=1;i<=n;i++) if(g[i].size()==1) leaf.push_back(i); else r=i;
        dep[r]=0;
        dfs1(r);
        vector <int> leafdis;
        for(int i:leaf) leafdis.push_back(dis[i]&1);
        if(*min_element(leafdis.begin(),leafdis.end()) == *max_element(leafdis.begin(),leafdis.end())) {
            cout<<1<<" ";
        }
        else {
            cout<<3<<" ";
        }
        cout<<ans+n-1;
    }
    
  • 相关阅读:
    Linux常用的一些基础命令
    配置Samba(CIFS)
    部署mariadb高可用
    k8s-kuberntets
    获取企业微信的corpID,sercret,access_token,部门设置列表
    Windows系统同步软件
    windows系统ms-17-010 漏洞补丁微软下载地址
    Linux下使用Docker教程
    sqlserver必须安装的组件
    windows系统安全加固方案
  • 原文地址:https://www.cnblogs.com/mollnn/p/12812700.html
Copyright © 2011-2022 走看看