构造+树形dp+思维——cf1341F

这种构造题实在是太耗脑细胞了,看题解又不太甘心。。策略改来改去弄了半天

/*
首先有个结论:每个点至少要用掉的时间=这个点的度数
然后进行构造;设tv为u->v时到v的时间,让v回到u时的时间也是tv,设u有k个子树,那么u只要分配给这k个子树[1,k+1]这些数值即可
              再设tu为fa[u]->u的时间,那么要从u->fa[u]时,u的时间必须在tu-1,如果u给子树分配了u-1,那么这个子树必须最后才访问 
*/
#include<bits/stdc++.h>
using namespace std;
#define N 200005

vector<int>G[N];
vector<pair<int,int> >ans;
int n,d[N],mx;

void dfs(int u,int pre,int tu){//tu表示从父节点进入到u的时间 
    ans.push_back(make_pair(u,tu));
    vector<int>son;
    for(auto v:G[u])
        if(v!=pre)son.push_back(v);
        
    int now=tu;
    for(auto v:son){
        if(now==mx){
            now=mx-son.size()-1;
            ans.push_back(make_pair(u,now));
        }
        ++now;
        dfs(v,u,now);
        ans.push_back(make_pair(u,now));
    }
    
    if(u!=1 && now!=tu-1){
        now=tu-1;
        ans.push_back(make_pair(u,now));
    }
}

int main(){
    cin>>n;
    for(int i=1;i<n;i++){
        int u,v;scanf("%d%d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
    for(int i=1;i<=n;i++)d[i]=G[i].size(),mx=max(mx,d[i]);
    dfs(1,1,0);
    
    cout<<ans.size()<<'\n';
    for(auto p:ans)
        cout<<p.first<<" "<<p.second<<'\n';
} 

猜你喜欢

转载自www.cnblogs.com/zsben991126/p/12820041.html
今日推荐