URAL 1069 Prufer Code 树结构脑洞题
2017-07-12 22:11
316 查看
1069. Prufer Code
Time limit: 0.25 secondMemory limit: 8 MB
A tree (i.e. a connected graph without cycles) with vertices is given (N ≥ 2). Vertices of the tree are numbered by the integers 1,…,N. A Prufer code for the tree is built as follows:
a leaf (a vertex that is incident to the only edge) with a minimal number is taken. Then this vertex and the incident edge are removed from the graph, and the number of the vertex that was adjacent to the leaf is written down. In the obtained graph once again
a leaf with a minimal number is taken, removed and this procedure is repeated until the only vertex is left. It is clear that the only vertex left is the vertex with the number N. The written down set of integers (N−1 numbers, each in a range
from 1 to N) is called a Prufer code of the graph.
Your task is, given a Prufer code, to reconstruct a tree, i.e. to find out the adjacency lists for every vertex in the graph.
You may assume that 2 ≤ N ≤ 7500
Input
A set of numbers corresponding to a Prufer code of some tree. The numbers are separated with a spaces and/or line breaks.Output
Adjacency lists for each vertex. Format: a vertex number, colon, numbers of adjacent vertices separated with a space. The vertices inside lists and lists itself should be sorted by vertex number inan ascending order (look at sample output).
Sample
input | output |
---|---|
2 1 6 2 6 | 1: 4 6 2: 3 5 6 3: 2 4: 1 5: 2 6: 1 2 |
记录的编号中,没有出现过的节点就是原始树中的叶子节点。因为如果某节点不是叶子节点,则它的子节点被删除时它必定被记录编号。
每次删点选取的是编号最小的叶节点,可以想象,这个被删的节点在之后的所有编号中都不会出现,而这个叶节点的编号又最小,所以每次删掉的是之后的编号中没有出现过的编号最小的根节点。
而编号最小可以用优先队列维护,不断把之后编号中未出现的编号加入队列。
#include <cstdio> #include <iostream> #include <vector> #include <string.h> #include <map> #include <algorithm> #include <queue> #include <math.h> #include <cmath> #define mem(a) memset(a,0,sizeof(a)) using namespace std; typedef long long ll; const int maxn=8005; int a[maxn],son[maxn]; vector<int> v[maxn]; priority_queue<int,vector<int>,greater<int> > q; int main() { int n,i,sum,j,min; // n=1; // while (scanf("%d",&a )!=EOF) n++; scanf("%d",&n); for (i=1;i<n;i++) scanf("%d",&a[i]); mem(son); for (i=1;i<n;i++) { son[a[i]]++; } for (i=1;i<=n;i++) { if (!son[i]) q.push(i); } for (i=1;i<n;i++) { int now=q.top(); v[a[i]].push_back(now); v[now].push_back(a[i]); q.pop(); son[a[i]]--; if (!son[a[i]]) q.push(a[i]); } for (i=1;i<=n;i++) { sort(v[i].begin(),v[i].end()); int size=v[i].size(); printf("%d:",i); for (j=0;j<size;j++) { printf(" %d",v[i][j]); } printf("\n"); } return 0; }
相关文章推荐
- ural 1069. Prufer Code
- URAL1069 Prufer Code
- URAL 1069 Prufer Code
- URAL 1069 Prufer Code(模拟)
- ural 1069. Prufer Code
- URAL 1069 Prufer Code 优先队列
- URAL 1069. Prufer Code 读懂题意逆推模拟
- 1069. Prufer Code
- URAL1069
- 数据结构(脑洞题,BIT):COGS 2394. 比赛
- URAL - 1069 Prufer Code (图的重建)
- ural 1069
- ural 1069
- ural 1069. Prufer Code
- URAL 1822. Hugo II's War 树的结构+二分
- URAL 1822. Hugo II's War 树的结构+二分
- 最好的富勒烯结构生成程序-CaGe的简便使用方法
- 在.net 中 将线性结构数据列表转换为 XML 格式的层次结构
- C#循环结构应用实例-制作用户注册页面 推荐
- 数据结构之线性结构(循环链表)【三】