码迷,mamicode.com
首页 > 其他好文 > 详细

cf1286B——构造,启发式合并

时间:2020-01-07 00:45:35      阅读:116      评论:0      收藏:0      [点我收藏+]

标签:cin   +=   ret   bit   span   clu   fine   col   style   

/*
思路:借鉴 dsu on tree,自底往上进行合并
给每个叶子结点赋初始值为1,每个结点依次合并每个儿子
为了防止冲突,子树在被并入当前结点时,所有结点都要重新编号
最后把当前结点插到子树里去,由于又插进了一个结点,所以再重新编号一次
每个最多被重新编号n次,复杂度O(n^2) 
*/
#include<bits/stdc++.h>
#include<vector>
using namespace std;
#define N 2005

int n,p[N],c[N],id[N];
vector<int>G[N];
vector<int> subtree[N];
int root;

void dfs(int u,int pre){
    if(G[u].size()==1 && pre==0){
        subtree[u].push_back(u);
        id[u]=1;return;
    }
    
    for(auto v:G[u])
        if(v!=pre)dfs(v,u);
        
    int tot=0;
    for(auto v:G[u])if(v!=pre){
        for(auto x:subtree[v]){
            subtree[u].push_back(x);
            id[x]+=tot;
        }
        tot+=subtree[v].size();
        subtree[v].clear();
    }
    
    stack<int>stk;
    while(stk.size())stk.pop();
    
    while(subtree[u].size()>=c[u]){
        stk.push(subtree[u].back());
        subtree[u].pop_back();
    }
    subtree[u].push_back(u);
    id[u]=c[u];
    while(stk.size()){
        int now=stk.top();stk.pop();
        id[now]++;
        subtree[u].push_back(now);
    }
}

int size[N];
void getsize(int u,int pre){
    size[u]=1;
    for(auto v:G[u]){
        if(v==pre)continue;
        getsize(v,u);size[u]+=size[v];
    }
}

int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>p[i]>>c[i];
        c[i]++;
        G[i].push_back(p[i]);
        G[p[i]].push_back(i);
        if(p[i]==0)root=i;
    }
    
    getsize(root,0);
    for(int i=1;i<=n;i++)
        if(size[i]<c[i]){
            puts("NO");return 0;
        }
    
    dfs(root,0);
    puts("YES");
    for(int i=1;i<=n;i++)cout<<id[i]<<" ";
}

cf1286B——构造,启发式合并

标签:cin   +=   ret   bit   span   clu   fine   col   style   

原文地址:https://www.cnblogs.com/zsben991126/p/12159094.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!