• 2020牛客暑期多校训练营(第二场)C


    Description

    给定一棵无根树,求它的最小链覆盖,输出方案。

    Solution

    以任意非叶子结点定根,如果叶子结点个数为奇数则手工在根上再挂一个

    对叶子结点按 DFS 序排序,设有 (2s) 个,则 (1 o s+1, 2 o s+2,...),两两匹配即可

    多挂的那个结点记得在输出时改成根

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 1000005;
    
    int dfn[N],n,m,t1,t2,t3;
    vector <int> g[N];
    int vis[N];
    vector <int> leaf;
    int d[N],ind;
    
    void dfs(int p)
    {
        vis[p]=1;
        dfn[p]=++ind;
        for(int q:g[p])
        {
            if(!vis[q])
            {
                dfs(q);
            }
        }
    }
    
    signed main()
    {
        ios::sync_with_stdio(false);
        cin>>n;
        if(n==1)
        {
            cout<<"1 1"<<endl;
            return 0;
        }
        if(n==2)
        {
            cout<<"1 2"<<endl;
            return 0;
        }
        for(int i=1;i<n;i++)
        {
            cin>>t1>>t2;
            g[t1].push_back(t2);
            g[t2].push_back(t1);
            d[t1]++;
            d[t2]++;
        }
        int sum=0,root;
        for(int i=1;i<=n;i++)
        {
            if(d[i]==1) ++sum, leaf.push_back(i);
            else root=i;
        }
        if(sum&1)
        {
            ++sum;
            leaf.push_back(n+1);
            g[n+1].push_back(root);
            g[root].push_back(n+1);
        }
        dfs(root);
        sort(leaf.begin(),leaf.end(),[](int x,int y){return dfn[x]<dfn[y];});
        cout<<sum/2<<endl;
        for(int i=0;i<sum/2;i++)
        {
            cout<<min(n,leaf[i])<<" "<<min(n,leaf[i+sum/2])<<endl;
        }
    }
    
    
  • 相关阅读:
    Php排序
    php导出excel表
    yii的多表查询
    MySQL中自定义排序
    jquery中的obj.attr()和obj.data
    PhpStorm快捷键
    记2019年目标之一没有996的大数据分析BI实战历程
    2018年传统公司技术部门技术变迁和2019展望
    mpvue微信小程序开发随笔
    docker toolbox的redis 配置主从及哨兵模式保证高可用
  • 原文地址:https://www.cnblogs.com/mollnn/p/13321960.html
Copyright © 2020-2023  润新知