题目大意:输入一颗无根树的括号序列,求这棵树的普吕弗序列。

分析思路:

1)普吕弗序列,可以参考维基百科,其做法是找出树中编号最小的叶子节点,并将此叶子节点及边删除,并输出其邻接的节点标号;

2)递归地构造树,可以使用list<int> 数组来表示一个“邻接表”,以存储构造的树;

3)使用优先队列来进行删除,奈何priority_queue没有迭代器访问,只能用堆排序,取最值;

代码:

#include<iostream>
#include<vector>
#include<map>
#include<queue>
#include<string>
#include<algorithm>
#include<fstream>
#include<list>
using namespace std; struct nodeAndDegree
{
int degree; //度
int nodeNumber; //结点编号
bool operator < (const nodeAndDegree& n1)const
{
return degree == n1.degree ? (nodeNumber > n1.nodeNumber) : (degree > n1.degree);
}
}; const int MAX_LEN = 55;
list<int> vGraph[MAX_LEN];
vector<int> v;
int rootNumber = 0; void dfs(int start, int end, int parent, string str)
{
if (start == end) //只有单个点
{
return;
} //放入邻接矩阵
int currentNode = 0;
for (int i = start + 1; i <= end - 1; i++)
{
if (str[i] == ' ' || str[i] == '\0' || str[i] == '(')
{
break;
}
currentNode = currentNode * 10 + (int)(str[i] - 48);
} //放入邻接矩阵
vGraph[parent].push_back(currentNode);
vGraph[currentNode].push_back(parent);
v.push_back(currentNode); int mark = 0;
int tmpStart = -1;
for (int i = start + 1; i <= end - 1; i++)
{
if (str[i] == '(')
{
mark++;
if (tmpStart == -1) tmpStart = i;
continue;
} if (str[i] == ')')
{
mark--;
if (mark == 0)
{
dfs(tmpStart, i, currentNode, str);
tmpStart = -1;
}
}
}
} void print_prufer_sequnce()
{
//首先修改根节点对应的长度
int tmp = vGraph[0].front();
vGraph[tmp].remove(0); vector<nodeAndDegree> listNodeDegree;
for (int i = 0; i < v.size(); i++)
{
nodeAndDegree *nd = new nodeAndDegree();
nd->nodeNumber = v[i];
nd->degree = vGraph[v[i]].size(); listNodeDegree.push_back(*nd);
} int n = v.size() - 1;
int index = 0; while (index < n)
{
make_heap(listNodeDegree.begin(), listNodeDegree.end());
int number = listNodeDegree[0].nodeNumber; //当前结点
int front = vGraph[number].front(); cout << front ;
if (index != n - 1)
{
cout << " ";
}
vGraph[front].remove(number);
vGraph[number].remove(front);
for (int j = 1; j < listNodeDegree.size(); j++)
{
if (listNodeDegree[j].nodeNumber == front)
{
listNodeDegree[j].degree--;
break;
}
} listNodeDegree.erase(listNodeDegree.begin()); index++;
}
} int main()
{
string s;
//fstream cin("1097.txt");
while (getline(cin, s))
{
for (int i = 0; i < MAX_LEN; i++)
{
vGraph[i].clear();
}
v.clear();
dfs(0, s.size() - 1, 0, s);
print_prufer_sequnce();
cout << endl;
}
return 0;
}

以纪念我那逝去的耗费精力的兴奋的AC。

zoj 1097 普吕弗序列的更多相关文章

  1. 线性时间构造普吕弗(Prüfer)序列

    tree -> sequence 首先预处理数组 deg[N], deg[i]表示编号为i的节点的度数,我们每次要删除的节点肯定是 满足deg[i]=1 的编号最小节点, 首先找到所有叶子并选出 ...

  2. 计蒜客NOIP模拟赛(2) D2T1 劫富济贫

    [问题描述] 吕弗·普自小从英国长大,受到骑士精神的影响,吕弗·普的梦想便是成为一位劫富济贫的骑士. 吕弗·普拿到了一份全国富豪的名单(不在名单上的都是穷人),上面写着所有富豪的名字以及他们的总资产, ...

  3. hdu 1394 zoj 1484 求旋转序列的逆序数(并归排序)

    题意:给出一序列,你可以循环移动它(就是把后面的一段移动到前面),问可以移动的并产生的最小逆序数. 求逆序可以用并归排序,复杂度为O(nlogn),但是如果每移动一次就求一次的话肯定会超时,网上题解都 ...

  4. 无向图的完美消除序列 判断弦图 ZOJ 1015 Fish net

       ZOJ1015 题意简述:给定一个无向图,判断是否存在一个长度大于3的环路,且其上没有弦(连接环上不同两点的边且不在环上). 命题等价于该图是否存在完美消除序列. 所谓完美消除序列:在 vi,v ...

  5. ZOJ 3963 Heap Partition set维护。给一个序列,将其划分成尽量少的序列,使每一个序列满足按照顺序构造二叉树,父母的值<=孩子的值。

    Heap Partition Time Limit: Seconds Memory Limit: KB Special Judge A sequence S = {s1, s2, ..., sn} i ...

  6. ZOJ 3795 Grouping 求最长链序列露点拓扑

    意甲冠军:特定n积分.m向边条. 该点被划分成多个集合随机的每个集合,使得2问题的关键是无法访问(集合只能容纳一个点) 问至少需要被分成几个集合. 假设没有戒指,接着这个话题正在寻求产业链最长的一个有 ...

  7. (队列的应用5.3.1)ZOJ 3210 A Stack or A Queue?根据进入结构的序列和离开结构的序列确定是stack还是queue)

    /* * ZOJ_3210.cpp * * Created on: 2013年10月30日 * Author: Administrator */ #include <iostream> # ...

  8. ZOJ 2319 Beatuiful People(单调递增序列的变形)

    Beautiful People Time Limit: 5 Seconds      Memory Limit: 32768 KB      Special Judge The most prest ...

  9. 弗拉特利定律:Illumina怎样缔造基因革命

    蕾妮·瓦林特(Renee Valint)的女儿谢尔碧(Shelby)在2000年出生时.看起来虚弱无力,就如同一仅仅耷拉着的布娃娃.谢尔碧学着走路和说话,但学得很慢.错过了儿童发展的重要阶段.到4岁时 ...

随机推荐

  1. Seventh scrum meeting - 2015/11/1

    新的一月开始了!今天是周末,所以大家的开发进度有点减慢,享受一个愉快的周末~ 今天大家的开发都没有遇到什么问题,因为这几天下来,大家对android的开发流程都比较熟悉了,暂时不会遇到新的问题了. 我 ...

  2. cocos2d::Vector

    C++中的vector使用范例 一.概述 vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector是一个容器,它能够存放各种类型的对象,简 ...

  3. 粒子滤波particle filter和目标跟踪

    粒子滤波用于跟踪,参考:http://www.cnblogs.com/tornadomeet/archive/2012/03/18/2404817.html http://blog.csdn.net/ ...

  4. java笔试二

    16.同步和异步有何异同,在什么情况下分别使用他们?举例说明.如果数据将在线程间共享.例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必 ...

  5. linux 搭建hexo博客

    搭建环境: CentOS 6.5 1.安装git的编译包 yum -y install gcc zlib-devel openssl-devel perl cpio expat-devel gette ...

  6. js 函数定义三种方式

    <p>Js 函数定义的三种方式:</p> <br> <p>方式一:function</p> <script type="te ...

  7. sys.path和os.path

    sys.path和os.path1.sys.path是python搜索模块的路径集合,是个list:os.path是os的一个模块,是操作文件和目录的模块 2.sys.path和PYTHONPATH首 ...

  8. 【转】mysql忘记root密码的解决方法

    本文收集于本人的笔记本,由于找不到原文出处.在此省略,如哪位知道可以联系我加上. 方法一:在windows下:1.打开命令行(DOS)窗口,停止mysql服务: net stop mysql 2.在D ...

  9. 4.python函数基础

    一.函数 1.函数简介 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但 ...

  10. codeforces A. Xenia and Divisors 解题报告

    题目链接:http://codeforces.com/problemset/problem/342/A 题目意思:给出n个数,找出n/3个组且每组有3个数,这三个数必须要符合两个条件:1.a < ...