zoukankan      html  css  js  c++  java
  • CF-div3-611-F. DIY Garland 优先队列 构造树

    思路

    参考队友博客:https://www.cnblogs.com/AaronChang/p/12129861.html

    思考如何构造一个树:(亮度低与重要度低)的二者匹配;
    什么时候重要度低,就叶节点开始(从下到上)。

    所以,从叶节点出发,往上构造,度数为0的就是叶节点加入优先队列,与重要度从小到大相匹配。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    /*
    思考如何构造一个树:权值小的先匹配,什么时候权值小,(亮度低,重要度低)二者匹配 
    
    从叶节点出发,往上构造,度数为0的就是叶节点 
    */
    
    const int maxn = 2e5+10;
    priority_queue<int,vector<int>,greater<int> > q;
    vector<int> lamps; //main主灯 
    int deg[maxn];
    int n;
    vector<pair<int,int> > ans;
    
    int main(){
    	cin>>n;
    	int root = 1; //根 
    	for(int i=1;i<=n-1;i++){
    		int lamp;
    		cin>>lamp;
    		if(i == 1) root = lamp; //第一个出现的(重要性高)就是根 
    		deg[lamp]++;
    		lamps.push_back(lamp);
    	}
    	for(int i=1;i<=n;i++){
    		if(deg[i] == 0) q.push(i); //叶节点 辐灯 
    	}
    	while(!q.empty()){
    		int auxiliaryLamp = q.top();
    		q.pop();
    		int mainLamp = lamps[lamps.size()-1];
    		lamps.pop_back();
    		deg[mainLamp]--; //连接了一个灯 所以度数-1 
    		if(deg[mainLamp] == 0) q.push(mainLamp); //判断是否为叶节点 
    		ans.push_back({mainLamp,auxiliaryLamp}); //存放树的边 
    		if(ans.size() == n-1) break;
    	}
    	cout<<root<<endl;
    	for(int i=ans.size()-1;i>=0;i--){
    		cout<<ans[i].first<<" "<<ans[i].second<<endl;
    	}
    	return 0;
    } 
    
  • 相关阅读:
    查找算法:二分查找法(折半查找)
    钞票找零-贪心,动态规划算法
    PHP7与php5
    网站高并发解决方案(理论知识) 二
    loj#6566. 月之都的密码
    我的 Linux 配置
    CTSC2011 幸福路径
    WC2018 即时战略
    uoj#460 新年的拯救计划
    bzoj 5016 一个简单的询问
  • 原文地址:https://www.cnblogs.com/fisherss/p/12346723.html
Copyright © 2011-2022 走看看