• 构造,贪心,拓扑排序变形——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<<'
    ';
    } 
  • 相关阅读:
    9-day9-生成器-列表解析-三元表达式-
    8-day8-列表解析-装饰器-迭代器
    7-day7-闭包函数-装饰器-函数2
    6-day6-函数-1
    5-day5-字符编码-函数-文件操作
    hive 跨年周如何处理
    nginx 安装部署
    logstash 读取kafka output ES
    leedcode 001 之 Two Sum 42.20% Easy
    大数据调度与数据质量的重要性
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12284104.html
Copyright © 2020-2023  润新知