题意:在树中,每次删去节点值最小的叶子结点。

  每删去一个点,就给出与这相连的点的值,直到最后只剩下一个根结点,给这N-1个数,重新建立这个树。

思路:

  给出的节点号按次序存入到数组a中,将未给出的数存入到rest数组中去,并从小到大排序。

  每次取一个给出的节点,那么我们需要求出与该点相连的被删去的点v。

   而点v必定为 “不会在之后的数据中出现的值(即之后删除的叶子节点中再也没有与之相连的,即改点为叶子节点)” 和 “当前rest数组中最小的值”  中的最小值。

  那么只要预处理一下,对于给出的节点号u,num[u][i]表示在给出的n-1个节点号(标号为0~n-2)中,第i个以后(包括第i个)有几个u。

  这样对于第i个节点号,u=a[i],求与它相连的v的时候,只要遍历一下所有num[u][i]=0并且之前还没被用过的情况,选取其中最小的值,与当前的rest数组中最小的值比较,最小的那个即使v。

   将n-1对(u,v)存入到另一个数组,最后建树即可。

不知道怎么回事,一开始用puts(),getline(),结果都是Output Limit Exceeded,可能自己使用有些错误吧。
后来看了网上别人用sstream类库读取数据的方法,这才AC。。。

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <algorithm>
  4. #include <string.h>
  5. #include <string>
  6. #include <vector>
  7. #include <sstream>
  8.  
  9. using namespace std;
  10. const int maxn=;
  11. int a[maxn];
  12. int num[maxn][maxn]; //num[u][i]表示在a[i]以后(包括a[i])有几个a[i]。
  13. int vis[maxn]; //vis[i]=1表示i在给出的数据中,=0即剩下的点
  14. int rest[maxn]; //存储给出的数据中未出现的点的编号
  15. int used[maxn]; //标记哪些点已经用过了
  16. vector<int>son[maxn];
  17. struct Node{
  18. int u,v; //u是给出的数据中的节点,v是与它们相连的被删去的节点
  19. }node[maxn];
  20.  
  21. void dfs(int u){
  22. printf("(");
  23. printf("%d",u);
  24. for(int i=;i<son[u].size();i++){
  25. printf(" "); //不打空格,也AC
  26. dfs(son[u][i]);
  27. }
  28. printf(")");
  29. }
  30. int main()
  31. {
  32. string buf;
  33. char ch,str[];
  34. int idx,u,v,minv;
  35. while(getline(cin,buf)){
  36. for(int i=;i<maxn;i++)
  37. son[i].clear();
  38. memset(vis,,sizeof(vis));
  39. memset(num,,sizeof(num));
  40. memset(used,,sizeof(used));
  41.  
  42. stringstream ss(buf);
  43. for(idx=;ss>>a[idx];idx++);
  44. //预处理num[][]。
  45. for(int i=idx-;i>=;i--){
  46. vis[a[i]]=; //标记出现过的节点号
  47. num[a[i]][i]=num[a[i]][i+]+;
  48. for(int j=;j<idx;j++){
  49. if(a[j]!=a[i])
  50. num[a[j]][i]=num[a[j]][i+];
  51. }
  52. }
  53. int rlen=,r=; //rlen为rest数组的长度,r是指针,指向当前最小的值
  54. for(int i=;i<=a[idx-];i++){
  55. if(!vis[i]){
  56. rest[rlen++]=i;
  57. }
  58. }
  59. sort(rest,rest+rlen);
  60. int k=;
  61. for(int i=;i<idx;i++){
  62. u=a[i];
  63. minv=;
  64. //选取num[a[j]]=0和rest[r]中的最小值,即为与u相连的被删去的节点。
  65. //注意a[j]是未被使用过的,used[a[j]]=1表明a[j]在之前就被删去了,也就不可能在这次删去节点a[j]
  66. for(int j=;j<idx;j++){
  67. if(num[a[j]][i]== && a[j]<minv && !used[a[j]]){
  68. minv=a[j];
  69. }
  70. }
  71. if(r<rlen && rest[r]<minv){
  72. minv=rest[r];
  73. r++;
  74. }
  75. used[minv]=;
  76. node[k].u=u;
  77. node[k].v=minv;
  78. k++;
  79. }
  80. //建树
  81. for(int i=;i<k;i++){
  82. u=node[i].u;
  83. v=node[i].v;
  84. son[u].push_back(v);
  85. }
  86. //即如果读入的一行是空的,那么就只有1个节点1
  87. if(a[idx-]==)
  88. a[idx-]=;
  89. dfs(a[idx-]);
  90. printf("\n");
  91. }
  92. return ;
  93. }

POJ 2568/ZOJ 1965 Decode the Tree的更多相关文章

  1. POJ 3076 / ZOJ 3122 Sudoku(DLX)

    Description A Sudoku grid is a 16x16 grid of cells grouped in sixteen 4x4 squares, where some cells ...

  2. POJ 1562 && ZOJ 1709 Oil Deposits(简单DFS)

    题目链接 题意 : 问一个m×n的矩形中,有多少个pocket,如果两块油田相连(上下左右或者对角连着也算),就算一个pocket . 思路 : 写好8个方向搜就可以了,每次找的时候可以先把那个点直接 ...

  3. 三分 POJ 2420 A Star not a Tree?

    题目传送门 /* 题意:求费马点 三分:对x轴和y轴求极值,使到每个点的距离和最小 */ #include <cstdio> #include <algorithm> #inc ...

  4. poj 3100 (zoj 2818)||ZOJ 2829 ||ZOJ 1938 (poj 2249)

    水题三题: 1.给你B和N,求个整数A使得A^n最接近B 2. 输出第N个能被3或者5整除的数 3.给你整数n和k,让你求组合数c(n,k) 1.poj 3100 (zoj 2818) Root of ...

  5. POJ 2567 Code the Tree &amp; POJ 2568 Decode the Tree Prufer序列

    题目大意:2567是给出一棵树,让你求出它的Prufer序列.2568时给出一个Prufer序列,求出这个树. 思路:首先要知道Prufer序列.对于随意一个无根树,每次去掉一个编号最小的叶子节点,并 ...

  6. poj 1436 && zoj 1391 Horizontally Visible Segments (Segment Tree)

    ZOJ :: Problems :: Show Problem 1436 -- Horizontally Visible Segments 用线段树记录表面能被看见的线段的编号,然后覆盖的时候同时把能 ...

  7. ZOJ 3686 A Simple Tree Problem

    A Simple Tree Problem Time Limit: 3 Seconds      Memory Limit: 65536 KB Given a rooted tree, each no ...

  8. [POJ 2420] A Star not a Tree?

    A Star not a Tree? Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4058   Accepted: 200 ...

  9. poj 1080 zoj 1027(最长公共子序列变种)

    http://poj.org/problem?id=1080 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=27 /* zoj ...

随机推荐

  1. Populating Next Right Pointers in Each Node II

    题目地址: https://oj.leetcode.com/problems/populating-next-right-pointers-in-each-node-ii/ 关键思路:讲节点的左右子节 ...

  2. L014-oldboy-mysql-dba-lesson14

          L014-oldboy-mysql-dba-lesson14             来自为知笔记(Wiz) 附件列表

  3. 《linux源代码包的编译安装》RHEL6

    linux下源代码包的编译安装其实没那么复杂. 我是win7系统装的虚拟机,就简单说下: 举个简单的例子: http://www.openssl.org/ 这是openssl的官网,下载openssl ...

  4. tp中让头疼似懂非懂的create

    项目中多次用到create() 只能它是表单验证,不过好出错,痛下心扉好好了解理解它的来龙去脉和所用的用法 一:通过create() 方法或者 赋值的方法生成数据对象,然后写入数据库 $model = ...

  5. iOS相机操作笔记

    最近忙于项目,需要拍摄图片,这里先列出部分测试代码. // // FirstViewController.m // UiTest // // Created by Tang Huaming on 16 ...

  6. DevExpress控件水印文字提示

    ButtonEdit.Properties.NullValuePrompt = "提示"; ButtonEdit.Properties.NullValuePromptShowFor ...

  7. lower_bound和upper_bound

    lower_bound:返回大于或等于val的第一个元素位置 upper_bound:返回大于val的第一个元素位置 两个函数用的都是二分查找

  8. jQuery select的操作代码

    jQuery對select的操作的实际应用代码. //改變時的事件  复制代码代码如下: $("#testSelect").change(function(){ //事件發生  j ...

  9. centos问题集锦

    一. 为什么新装的centos系统无法使用xshell,putty等工具连接? 原因:sshd服务没有启动. 解决: 1)使用命令rpm -qa | grep ssh查看是否已经安装了ssh 2)使用 ...

  10. 无DLL线程注入

    注意要在release方式编译 //线程函数 DWORD WINAPI RemoteThreadProc(LPVOID lpParam) {      PDATA pData = (PDATA)lpP ...