zoj 1097 普吕弗序列
题目大意:输入一颗无根树的括号序列,求这棵树的普吕弗序列。
分析思路:
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 普吕弗序列的更多相关文章
- 线性时间构造普吕弗(Prüfer)序列
tree -> sequence 首先预处理数组 deg[N], deg[i]表示编号为i的节点的度数,我们每次要删除的节点肯定是 满足deg[i]=1 的编号最小节点, 首先找到所有叶子并选出 ...
- 计蒜客NOIP模拟赛(2) D2T1 劫富济贫
[问题描述] 吕弗·普自小从英国长大,受到骑士精神的影响,吕弗·普的梦想便是成为一位劫富济贫的骑士. 吕弗·普拿到了一份全国富豪的名单(不在名单上的都是穷人),上面写着所有富豪的名字以及他们的总资产, ...
- hdu 1394 zoj 1484 求旋转序列的逆序数(并归排序)
题意:给出一序列,你可以循环移动它(就是把后面的一段移动到前面),问可以移动的并产生的最小逆序数. 求逆序可以用并归排序,复杂度为O(nlogn),但是如果每移动一次就求一次的话肯定会超时,网上题解都 ...
- 无向图的完美消除序列 判断弦图 ZOJ 1015 Fish net
ZOJ1015 题意简述:给定一个无向图,判断是否存在一个长度大于3的环路,且其上没有弦(连接环上不同两点的边且不在环上). 命题等价于该图是否存在完美消除序列. 所谓完美消除序列:在 vi,v ...
- ZOJ 3963 Heap Partition set维护。给一个序列,将其划分成尽量少的序列,使每一个序列满足按照顺序构造二叉树,父母的值<=孩子的值。
Heap Partition Time Limit: Seconds Memory Limit: KB Special Judge A sequence S = {s1, s2, ..., sn} i ...
- ZOJ 3795 Grouping 求最长链序列露点拓扑
意甲冠军:特定n积分.m向边条. 该点被划分成多个集合随机的每个集合,使得2问题的关键是无法访问(集合只能容纳一个点) 问至少需要被分成几个集合. 假设没有戒指,接着这个话题正在寻求产业链最长的一个有 ...
- (队列的应用5.3.1)ZOJ 3210 A Stack or A Queue?根据进入结构的序列和离开结构的序列确定是stack还是queue)
/* * ZOJ_3210.cpp * * Created on: 2013年10月30日 * Author: Administrator */ #include <iostream> # ...
- ZOJ 2319 Beatuiful People(单调递增序列的变形)
Beautiful People Time Limit: 5 Seconds Memory Limit: 32768 KB Special Judge The most prest ...
- 弗拉特利定律:Illumina怎样缔造基因革命
蕾妮·瓦林特(Renee Valint)的女儿谢尔碧(Shelby)在2000年出生时.看起来虚弱无力,就如同一仅仅耷拉着的布娃娃.谢尔碧学着走路和说话,但学得很慢.错过了儿童发展的重要阶段.到4岁时 ...
随机推荐
- [ruby on rails] 跟我学之(5)显示所有数据
之前的index页,显示的是hello world,现在将其修改为显示我们在rails console里面录入的数据. 1. 修改action 如之前的章节<[ruby on rails] 跟我 ...
- 在Java中>、>>、>>>三者的区别
Java,是由Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台的总称.用Java实现的HotJava浏览器(支持Java applet)显示了Java的魅力 ...
- 【转】Spring@Autowired注解与自动装配
1 配置文件的方法 我们编写spring 框架的代码时候.一直遵循是这样一个规则:所有在spring中注入的bean 都建议定义成私有的域变量.并且要配套写上 get 和 set方法. Boss ...
- iOS 中NSOperationQueue,Grand Central Dispatch , Thread的上下关系和区别
In OS X v10.6 and later, operation queues use the libdispatch library (also known as Grand Central D ...
- block引发的陷阱
block在项目的开发中使用时非常频繁的,苹果官方也极力推荐使用block.其实,究其本质,block就是指向结构体的指针(可利用运行时机制查看底层生成的c代码).然而在使用block时会存在很多陷阱 ...
- Gym 100801A Alex Origami Squares (求正方形边长)
题目:传送门.(需要下载PDF) 题意:给定一个长方形,在长方形内部画三个相同的正方形,问正方形的边长最大是多大. 题解:根据长宽比例可以算出三种情况,如果长比宽大三倍以上,那么正方形边长就是宽:如果 ...
- Android Handler leak 分析及解决办法
In Android, Handler classes should be static or leaks might occur, Messages enqueued on the applicat ...
- 比较两个目录中的文件 diff -rq
[root@bass test]# mkdir A B [root@bass test]# tree A A └── lin 0 directories, 1 file [root@bass test ...
- Sublime Text : 创建工程
Sublime Text 可以很方便地管理多个工程.使用Sublime Text的Projects,可以将不同根目录的文件组织起来成为一个工程,而不用将所有的文件都放到一个根目录下面. 1. 创建工程 ...
- oracle 执行计划详解
简介: 本文全面详细介绍oracle执行计划的相关的概念,访问数据的存取方法,表之间的连接等内容. 并有总结和概述,便于理解与记忆! +++ 目录 --- 一.相关的概念 ...