zoj 1097 普吕弗序列
2024-10-14 08:52:34
题目大意:输入一颗无根树的括号序列,求这棵树的普吕弗序列。
分析思路:
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。
最新文章
- scala的面向对象编程
- Weblogic的安装与配置
- ViewPager+GridView实现首页导航栏布局分页效果
- redis使用笔记
- Edge detection using LoG
- 如何设计PHP业务模块(函数/方法)返回结果的结构?
- HTML DOM(学习笔记一)
- Java基础知识强化27:Object类之toString()方法
- 测试工作中ADB命令实战
- Jenkins: 执行 PowerShell 命令
- sublime的插件
- centos7 下 安装部署nginx
- Fiddler抓包7-post请求(json)
- JS 设置盒子div 跳转
- Scrum Meeting NO.3
- 初学SSH 配置+错误总结
- 解决 java循环中使用 Map时 在put值时value值被覆盖的问题
- Centos6.6下安装nginx1.6.3
- 方法$.data()和$.(&#39;#test&#39;).on()的使用
- Odoo中创建模块语句