zoukankan      html  css  js  c++  java
  • 构造,贪心,拓扑排序变形——cf1283F

    /*
    题意:一棵有根树,每个结点的权重为2^i,每条边的权重为其下子树结点的权重和
        现在按边权降序排序,每条边记录高度大的那个点,得到一个长度为n-1的序列
        根据这个序列构造出一棵合法的树
    性质:(fa[fa[u]],fa[u])必排在(fa[u],u)前面
    可以自底向上构造这棵树,先把叶子结点放进set里,然后倒序遍历数列,每次取出一个叶子结点到它的父节点里去,同时更新父亲结点的权值 
        如果父节点下的结点都被塞进去了,那么把这个父亲结点放进set,整个过程有点像拓扑排序 
    */ 
    #include<bits/stdc++.h>
    using namespace std;
    #define N 200005
    
    int n,a[N],son[N],Max[N];
    set<pair<int,int> >s;
    set<pair<int,int> >::iterator it;
    pair<int,int>edge[N];
    
    int main(){
        cin>>n;
        for(int i=1;i<n;i++)cin>>a[i],son[a[i]]++;
        for(int i=1;i<=n;i++)Max[i]=i;
        for(int i=1;i<=n;i++)if(!son[i])s.insert(make_pair(Max[i],i));
        for(int i=n-1;i>=1;i--){
            it=s.begin();
            edge[i].first=a[i];
            edge[i].second=(*it).second;
            son[a[i]]--;
            Max[a[i]]=max(Max[(*it).second],Max[a[i]]);
            if(son[a[i]]==0)
                s.insert(make_pair(Max[a[i]],a[i]));
            s.erase(it);
        }
        cout<<a[1]<<'
    ';
        for(int i=1;i<n;i++)
            cout<<edge[i].first<<" "<<edge[i].second<<'
    ';
    } 
  • 相关阅读:
    接口的幂等性原则
    SpringBoot热部署-解决方案
    @Resource 与 @Service注解的区别
    软件概要设计做什么,怎么做
    First Show
    Glide源码解析一,初始化
    android使用giflib加载gif
    android的APT技术
    RxJava的concat操作符
    RxJava基本使用
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12284104.html
Copyright © 2011-2022 走看看