首页 > 技术文章 > CF 981C Useful Decomposition

sdfzsyq 2018-07-06 19:49 原文

题面

题目大意

给定一棵树,要求划分出几条链,使这几条链交于一点。

解题思路

因为所有链都要交于一点,所以必须交于一个度数最多的点。这样就形成了一个菊花形。然后从这个点出发到它的子树,判断子树的度数是否小于等于2,如果不是,则不成立。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;
const int MAXN = 100005;

inline int rd(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=(x<<1)+(x<<3)+ch-48;ch=getchar();}
    return x*f;
}

int n,cnt,ans,st,mx;
int head[MAXN],num;
int to[MAXN<<1],nxt[MAXN<<1];
int deg[MAXN],p[MAXN];
bool flag;

inline void add(int bg,int ed){
    to[++cnt]=ed,nxt[cnt]=head[bg],head[bg]=cnt;
}

inline void dfs(int x,int pre){
    if(deg[x]>2) {flag=true;return;}
    if(deg[x]==1) {p[num]=x;return;}
    for(register int i=head[x];i;i=nxt[i]){
        int u=to[i];
        if(u==pre) continue;
        dfs(u,x);
    }
}

int main(){
    n=rd();
    for(register int i=1;i<n;i++){
        int x=rd(),y=rd();
        deg[x]++;deg[y]++;
        add(x,y);add(y,x);
        if(deg[x]>mx){
            mx=deg[x];
            st=x;
        }
        if(deg[y]>mx){
            mx=deg[y];
            st=y;
        }
    }
    for(register int i=head[st];i;i=nxt[i]){
        num++;
        dfs(to[i],st);
        if(flag==true) break;
    }
    if(flag) puts("No");
    else{
        puts("Yes");
        printf("%d\n",num);
        for(register int i=1;i<=num;i++)
            printf("%d %d\n",st,p[i]);
    }
}

推荐阅读