C Cover the Tree(选链覆盖树)

题:https://ac.nowcoder.com/acm/contest/5667/C

题意:选最少数量的“链”来覆盖整颗树,使树的每条边都至少被覆盖一次

分析:关键是理解证明过程:

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define MP make_pair
typedef long long ll;
const int mod=1e9+7;
const int M=2e5+5;
const int inf=0x3f3f3f3f;
const ll INF=1e18;
vector<int>g[M];
int a[M],du[M],dfn[M],cnt;
void dfs(int u,int fa){
    dfn[u]=++cnt;
    for(auto v:g[u])
        if(v!=fa)
            dfs(v,u);
}

int main(){
    int n;
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        g[u].pb(v);
        g[v].pb(u);
        du[u]++,du[v]++;
    }
    if(n==1)
        return puts("0"),0;
    else if(n==2)
        return printf("1
%1 2"),0;
    int tot=0,rt=1;
    for(int i=1;i<=n;i++)
        if(du[i]==1)
            a[tot++]=i;
        else
            rt=i;
    dfs(rt,0);
    sort(a,a+tot,[&](int x,int y){
        return dfn[x]<dfn[y];
    });
    int tmp=tot/2;
    if(tot&1){
        printf("%d
",tmp+1);
        printf("%d %d
",rt,a[tot-1]);
    }
    else
        printf("%d
",tmp);
    for(int i=0;i<tmp;i++)
        printf("%d %d
",a[i],a[i+tmp]);
    return 0;
}
/**
8
1 2
2 3
3 4
3 5
1 7
7 6
7 8

*/
View Code
原文地址:https://www.cnblogs.com/starve/p/13298780.html