【转】ACM 2567 -- 树的Prufer编码
本文介绍北京大学ACM网站2567号题目的解法。介绍部分基本翻译自网站上的题目介绍。
(1 (2 (3)))
(6 (1 (4)) (2 (3) (5)))
2 3
2 1 6 2 6
| 1 2 #include 3 #include 4 #include 5 6 #define END 0 // 结束 7 #define L_BRACKET 1 // 左括号 8 #define R_BRACKET 2 // 右括号 9 #define NUMBER 4 // 数 10 11 typedef struct _node 12 { 13 int value; // 节点值 14 int childs; // 子节点数 15 struct _node *parent; // 父节点 16 struct _node *first_child; // 第一个孩子节点 17 struct _node *sibling; // 下一个兄弟节点 18 }NODE; 19 20 typedef struct _token 21 { 22 int type; // 标记类型(左、右括号,数) 23 int value; // 值(仅当类型为数时有效) 24 }TOKEN; 25 26 typedef void (*FUNC)(NODE *); 27 static NODE *pSmallest = 0;// 指向最小的叶子节点 28 29 34 char *GetNextToken(char *input,TOKEN *pToken) 35 { 36 char *p,ch; 37 int value; 38 39 pToken->type = END; 40 41 p = input; 42 while ((ch = *p) && ch != '(' && ch != ')' && !isdigit(ch)) 43 p++; 44 switch(ch) 45 { 46 case '(': pToken->type = L_BRACKET; p++; break; 47 case ')': pToken->type = R_BRACKET; p++; break; 48 default: 49 50 if (isdigit(ch)) 51 { 52 value = 0; 53 while ((ch = *p) && isdigit(ch)) 54 { 55 value = 10 * value + (ch - '0'); 56 p++; 57 } 58 pToken->type = NUMBER; 59 pToken->value = value; 60 } 61 break; 62 } 63 64 return (*p == '\0' ? 0 : p); 65 } 66 67 71 NODE *BuildTree(char *input) 72 { 73 char *p; 74 TOKEN token; 75 NODE *pCur,*pNew,*pRoot,*pLast; 76 77 p = input; pCur = pLast = pRoot = 0; 78 do 79 { 80 p = GetNextToken(p,&token); 81 switch(token.type) 82 { 83 case L_BRACKET: 84 break; 85 case R_BRACKET: 86 87 pLast = pCur; 88 if (0 != pCur) 89 pCur = pCur->parent; 90 break; 91 case NUMBER: 92 pNew = (NODE *)malloc(sizeof(NODE)); 93 memset(pNew,0,sizeof(NODE)); 94 pNew->value = token.value; 95 96 pNew->parent = pCur; 97 if (0 != pLast) 98 { 99 pLast->sibling = pNew; 100 pLast = pNew; 101 } 102 if (0 != pCur) 103 { 104 if (0 == pCur->childs++) 105 pCur->first_child = pNew; 106 } 107 else pRoot = pNew; 108 109 p = GetNextToken(p,&token); 110 if (token.type == L_BRACKET) 111 { 112 pCur = pNew; 113 pLast = 0; 114 } 115 else if (token.type == R_BRACKET) 116 pLast = pNew; 117 break; 118 } 119 }while (0 != p); 120 return pRoot; 121 } 122 123 127 void TravelTree(NODE *pRoot,FUNC func) 128 { 129 NODE *pCur; 130 if (0 == pRoot) return; 131 (*func)(pRoot); 132 pCur = pRoot->first_child; 133 while (pCur) 134 { 135 TravelTree(pCur,func); 136 pCur = pCur->sibling; 137 } 138 } 139 140 141 int IsLeafNode(NODE *pNode) 142 { 143 return (0 != pNode && (0 == pNode->childs && 0 != pNode->parent) 144 || (1 == pNode->childs && 0 == pNode->parent)); 145 } 146 147 148 void LeafValueCompare(NODE *pNode) 149 { 150 if (IsLeafNode(pNode)) 151 if (0 == pSmallest) pSmallest = pNode; 152 else if (pNode->value < pSmallest->value) 153 pSmallest = pNode; 154 } 155 156 161 NODE *ReleaseLeafNode(NODE *pRoot,NODE *pNode) 162 { 163 NODE *pParent,*pSibling; 164 if (0 == pNode->childs) 165 { 166 pParent = pNode->parent; 167 if (pParent) 168 { 169 pSibling = pParent->first_child; 170 if (pNode == pSibling) 171 pParent->first_child = pNode->sibling; 172 else 173 { 174 while (pSibling && pSibling->sibling != pNode) 175 pSibling = pSibling->sibling; 176 if (pSibling) 177 pSibling->sibling = pNode->sibling; 178 } 179 pParent->childs--; 180 } 181 free(pNode); 182 } 183 else 184 { 185 pRoot = pNode->first_child; 186 pRoot->parent = 0; 187 free(pNode); 188 } 189 return pRoot; 190 } 191 192 void ReleaseTree(NODE *pRoot) 193 { 194 NODE *pCur,*pNext; 195 if (pRoot) 196 { 197 pCur = pRoot->first_child; 198 while (pCur) 199 { 200 pNext = pCur->sibling; 201 ReleaseTree(pCur); 202 pCur = pNext; 203 } 204 free(pRoot); 205 } 206 } 207 208 int main(int argc,char *argv[]) 209 { 210 NODE *pRoot; 211 char line[250]; 212 int n; 213 while (!feof(stdin)) 214 { 215 line[0] = '\0'; 216 gets(line); 217 pRoot = BuildTree(line); 218 n = 0; 219 while (pRoot && pRoot->childs != 0) 220 { 221 pSmallest = 0; 222 TravelTree(pRoot,LeafValueCompare); // 遍历树 223 if (0 == pSmallest->childs) 224 printf(n++ ? " %d" : "%d",pSmallest->parent->value); 225 else 226 printf(n++ ? " %d" : "%d",pSmallest->first_child->value); 227 pRoot = ReleaseLeafNode(pRoot,pSmallest); 228 } 229 if (0 != pRoot) 230 { 231 printf("\n"); 232 ReleaseTree(pRoot); 233 } 234 } 235 return 0; 236 } 237 |
【转】ACM 2567 -- 树的Prufer编码的更多相关文章
- BZOJ1005--[HNOI2008]明明的烦恼(树的prufer编码)
1005: [HNOI2008]明明的烦恼 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 5768 Solved: 2253[Submit][Stat ...
- 树的Prufer 编码和最小生成树计数
Prufer数列 Prufer数列是无根树的一种数列.在组合数学中,Prufer数列由有一个对于顶点标过号的树转化来的数列,点数为n的树转化来的Prufer数列长度为n-2.它可以通过简单的迭代方 ...
- 树的prufer编码
prufer是无根树的一种编码方式,一棵无根树和一个prufer编码唯一对应,也就是一棵树有唯一的prufer编码,而一个prufer编码对应一棵唯一的树. 第一部分:树编码成prufer序列. 树编 ...
- 【51NOD1806】wangyurzee的树(Prufer编码,容斥原理,组合计数)
题意:有n个点和m条限制,每条限制限制了一个点的度数不能为某个数. 求合法的树的个数模10^9+7 n<=10^6 m<=17 思路:WYZ作业 首先m<=17显然是2^m容斥 枚举 ...
- 【Foreign】树 [prufer编码][DP]
树 Time Limit: 10 Sec Memory Limit: 256 MB Description Input Output Sample Input 3 2 2 1 Sample Outp ...
- 【转】prufer编码
既然有人提到了,就顺便学习一下吧,来源:http://greatkongxin.blog.163.com/blog/static/170097125201172483025666/ 一个含有n个点的完 ...
- 「模拟赛20180406」膜树 prufer编码+概率
题目描述 给定一个完全图,保证\(w_{u,v}=w_{v,u}\)且\(w_{u,u}=0\),等概率选取一个随机生成树,对于每一对\((u,v)\),求\(dis(u,v)\)的期望值对\(998 ...
- Luogu2290 [HNOI2004]树的计数 (组合计数,prufer编码)
这不prufer编码吗,防爆long long就行了啊 #include <iostream> #include <cstdio> #include <cstring&g ...
- Codeforces 1109D. Sasha and Interesting Fact from Graph Theory 排列组合,Prufer编码
原文链接https://www.cnblogs.com/zhouzhendong/p/CF1109D.html 题意 所有边权都是 [1,m] 中的整数的所有 n 个点的树中,点 a 到点 b 的距离 ...
随机推荐
- vue基础---事件处理
(1)事件监听 v-on 指令监听 DOM 事件,并在触发时运行JS代码 <div class="event_area"> {{message}} <button ...
- Ansible基于playbook批量修改主机名实战
Ansible基于playbook批量修改主机名 安装Ansible,相信这里也不用多说,大家都知道 说一下环境:这里的主机名是修改之后的,我先把其他两台的主机名改为别的 192.168.30.21 ...
- 【最短路】Dijkstra+ 链式前向星+ 堆优化(优先队列)
Dijkstra+ 链式前向星+ 优先队列 Dijkstra算法 Dijkstra最短路算法,个人理解其本质就是一种广度优先搜索.先将所有点的最短距离Dis[ ]都刷新成∞(涂成黑色),然后从起点 ...
- acm相关(纯转载)
我觉得很好的文章,之所以放随笔是为了让大家看到这些优秀的博文 acm如何起步 acm重点题型 动态规划题目总结 背包九讲阅读网站
- UVA - 11212 Editing a Book (IDA*搜索)
题目: 给出n(1<n<10)个数字组成的序列,每次操作可以选取一段连续的区间将这个区间之中的数字放到其他任意位置.问最少经过多少次操作可将序列变为1,2,3……n. 思路: 利用IDA* ...
- MySql报Packet for query is too large错误
mysql中执行sql的时候报以下错误:Packet for query is too large (1354 > 1024) 原因是mysql一次接收的报文太长,需要调整服务器参数max_al ...
- Python学习之前
编程语言的分类: 1.机器语言:直接以0和1编写指令代码,计算机能直接识别处理: 特点:运行速度最快,太复杂,开发效率低,可执行操作最多. 2.汇编语言:本质上依然是机器语言,用英文代替0和1,更容易 ...
- ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer
传送门:https://nanti.jisuanke.com/t/31462 本题是一个树上的问题:结点间路径问题. 给定一个有N×M个结点的网格,并给出结点间建立墙(即拆除边)的代价.花费最小的代价 ...
- Adobe AIR 代码签名证书使用指南
Symantec,Thawte,GlobalSign 签发的代码签名证书都可以签名AIR文件.如果您还没有代码签名证书,请联系易维信(EVTrust)购买Adobe AIR 代码签名证书. 1.签名工 ...
- BNUOJ 26224 Covered Walkway
Covered Walkway Time Limit: 10000ms Memory Limit: 131072KB This problem will be judged on HDU. Origi ...