codeforces 1003E Tree Constructing

http://www.elijahqi.win/archives/3921
考慮如何構造這棵樹我們只需要把直徑先構造出來然後在直徑上長毛即可

那麼每個直徑上的點保證他的深度不超過到直徑兩端距離的最小值即可

注意特判一些k=1或者k=2的小數據

#include<bits/stdc++.h>
using namespace std;
inline char gc(){
    static char now[1<<16],*S,*T;
    if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}
    return *S++;
}
inline int read(){
    int x=0,f=1;char ch=gc();
    while(!isdigit(ch)) {if (ch=='-') f=-1;ch=gc();}
    while(isdigit(ch)) {x=x*10+ch-'0',ch=gc();}
    return x*f;
}
const int N=4e5+10;
struct node{
    int x,y;
};
vector<node> a;int n,D,k,d[N],now,maxd,lt;
inline void dfs(int x,int dep){
    if (dep>maxd) return;
    if (x>n) return;vector<int> pd;
    while(d[x]&&lt) pd.push_back(now),--lt,a.push_back((node){x,now}),
    --d[now],++now,--d[x];
    for (int i=0;i<pd.size();++i) dfs(pd[i],dep+1);
}
int main(){
//  freopen("e.in","r",stdin);
    n=read();D=read();k=read();
    if(n<D+1) {puts("NO");return 0;}
    for (int i=1;i<=n;++i) d[i]=k;
    for (int i=2;i<=D+1;++i){
        --d[i-1];--d[i];a.push_back((node){i-1,i});
    }lt=n-D-1;now=D+2;
    for (int i=1;i<=D+1;++i) if(d[i]<0) {puts("NO");return 0;}
    for (int i=2;i<=D;++i){
        if(!lt) break;maxd=min(i-1,D+1-i);
        dfs(i,1);
    }
    if (lt) {puts("NO");return 0;}
    puts("YES");
    for (int i=0;i<a.size();++i) printf("%d %d\n",a[i].x,a[i].y);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章