• 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;
    } 
    
  • 相关阅读:
    张五常:思考的方法
    David Foster Wallace on Life and Work
    SQL SERVER SQL Agent服务使用小结
    js大全
    中国载人航天工程七大系统
    vc 编译遇到问题
    学习Excel技巧
    使用Request.ServerVariables获取环境变量
    c# 字符常用函数
    SQL数据同步
  • 原文地址:https://www.cnblogs.com/fisherss/p/12346723.html
Copyright © 2020-2023  润新知