首页 > 其他 > 详细

Prufer Code

时间:2018-07-29 23:46:18      阅读:279      评论:0      收藏:0      [点我收藏+]

 

题目链接https://vjudge.net/contest/241657#problem/D

 

题目大意

给你Prufer码,反推这棵树

 

解题思路

输入,记录每个节点出现的次数,然后设置优先队列(小的优先),用于保存叶子结点,然后根据Prufer码,每次分配队列的队首作为其子节点

 

注意

输入容易被卡

 

ac代码

#include <iostream>
#include <cstdio>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
const int N = 8000;
vector<int> v, edge[8000];
int in[N];
struct cmp
{
    bool operator () (int &a, int &b)
    {
        return a > b;
    }
};

int main()
{
    int n = 0, k, i, j;
    priority_queue<int, vector<int>, cmp>q;
    for(i = 1; i < N; i++)in[i] = 1;
    int a;
    while(~scanf("%d", &a))
    {
        v.push_back(a);
        in[a]++;
    }
    n = v.size()+1;
    in[n]--;
    for(i = 1; i <= n; i++)
    {
        if(in[i] == 1)
        {
            q.push(i);
        }
    }
    int f, leaf;
    for(i = 0; i < v.size(); i++)
    {
        f = v[i];
        leaf = q.top();
        q.pop();
        edge[f].push_back(leaf);
        edge[leaf].push_back(f);

        in[f]--;
        if(in[f] == 1)
        {
            q.push(f);
        }
    }
    for(i = 1; i <= n; i++)
    {
        printf("%d:", i);
        sort(edge[i].begin(), edge[i].end());
        for(j = 0; j < edge[i].size(); j++)
        {
            printf(" %d", edge[i][j]);
        }
        printf("\n");
    }
    return 0;
}

 

Prufer Code

原文:https://www.cnblogs.com/kangrrrr/p/9388212.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!