【转】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 的距离 ...
随机推荐
- sql之inner join
这个嘛...经常写sql写的我怀疑自己:算了还是记下来了再强调一遍!再强调一遍!再强调一遍!:虽然很傻逼... inner join(等值连接) 只返回两个表中联结字段相等的行
- Xmind的使用
Xmind是用来学习整理思维的工具
- eclipse 中导入 MyBatis 的源码
(1)选中 Mybatis-3.2.2.jar ,右击,在弹出的快捷菜单中选择 “Properties” 选项,进入属性界面. (2)进入属性界面后,选中 “Java Source Attachme ...
- Python关于导入模块的一些感想:
写项目的时候,碰到这种情况 程序业务为core,里面有两个目录,core1 和core2 core1中有三个模块,business main main1 程序入口为bin目录下的project ...
- 安装charles
简介: Charles主要的功能包括: 支持SSL代理.可以截取分析SSL的请求. 支持流量控制.可以模拟慢速网络以及等待时间(latency)较长的请求. 支持AJAX调试.可以自动将json或xm ...
- BZOJ 3747 洛谷 3582 [POI2015]Kinoman
[题解] 扫描线+线段树. 我们记第i部电影上次出现的位置是$pre[i]$,我们从$1$到$n$扫描,每次区间$(pre[i],i]$加上第i部电影的贡献$w[f[i]]$,区间$[pre[pre[ ...
- Codeforces 263B. Appleman and Card Game
B. Appleman and Card Game time limit per test 1 second memory limit per test 256 megabytes input ...
- Android第三方开源SeekBarCompat:音乐类播放器等APP进度条常用
Android第三方开源SeekBarCompat:音乐类播放器等APP进度条常用 Android平台原生的SeekBar设计简单,然而,比如现在流行的一些音乐播放器的播放进度控制条,如果直接使 ...
- HDU 1224 无环有向最长路
用bellman_ford的方法,将中间不断取较小值,修改为取较大值就可以了 #include <cstdio> #include <cstring> #include < ...
- [luoguP1351] 联合权值(Dfs)
传送门 距离为2的点会产生权值,第一问,只需要在dfs的时候把一个点相邻的点都处理出来就行. 具体处理方式看代码,然而这样只处理了一遍,最后在乘2就好了. 第二问只需要处理一个点相邻的点中最大的和次大 ...