POJ 2367 Genealogical tree(拓扑排序+dfs)

约定不等于承诺〃 2022-06-11 02:08 242阅读 0赞

The system of Martians’ blood relations is confusing enough. Actually, Martians bud when they want and where they want. They gather together in different groups, so that a Martian can have one parent as well as ten. Nobody will be surprised by a hundred of children. Martians have got used to this and their style of life seems to them natural.
And in the Planetary Council the confusing genealogical system leads to some embarrassment. There meet the worthiest of Martians, and therefore in order to offend nobody in all of the discussions it is used first to give the floor to the old Martians, than to the younger ones and only than to the most young childless assessors. However, the maintenance of this order really is not a trivial task. Not always Martian knows all of his parents (and there’s nothing to tell about his grandparents!). But if by a mistake first speak a grandson and only than his young appearing great-grandfather, this is a real scandal.
Your task is to write a program, which would define once and for all, an order that would guarantee that every member of the Council takes the floor earlier than each of his descendants.

Input

The first line of the standard input contains an only number N, 1 <= N <= 100 — a number of members of the Martian Planetary Council. According to the centuries-old tradition members of the Council are enumerated with the natural numbers from 1 up to N. Further, there are exactly N lines, moreover, the I-th line contains a list of I-th member’s children. The list of children is a sequence of serial numbers of children in a arbitrary order separated by spaces. The list of children may be empty. The list (even if it is empty) ends with 0.

Output

The standard output should contain in its only line a sequence of speakers’ numbers, separated by spaces. If several sequences satisfy the conditions of the problem, you are to write to the standard output any of them. At least one such sequence always exists.

Sample Input

  1. 5
  2. 0
  3. 4 5 1 0
  4. 1 0
  5. 5 3 0
  6. 3 0

Sample Output

  1. 2 4 5 3 1

题解:

很简单的一道裸的拓扑排序题目。。。是之前做过一题的英文版,还更水一些,之前的还要求要字典序最小

详细解释见我之前写的中文版的家谱树题:点击打开链接

代码:

  1. #include<algorithm>
  2. #include<iostream>
  3. #include<cstring>
  4. #include<stdio.h>
  5. #include<math.h>
  6. #include<string>
  7. #include<stdio.h>
  8. #include<queue>
  9. #include<stack>
  10. #include<map>
  11. #include<deque>
  12. using namespace std;
  13. int vis[105];//存该点有没有被输出过
  14. int a[105][105];//存每一个点的儿子
  15. int num[105],n,tag;//num计算每一个点的儿子数目
  16. void dfs(int ans)//ans记入输出了几个点
  17. {
  18. if(ans>=n||tag)//只要找到一个就全停
  19. {
  20. tag=1;
  21. return;
  22. }
  23. int i,j;
  24. int p[105];
  25. memset(p,0,sizeof(p));//初始化为0,如果还没输出的点中出现了这个点是他的儿子则这个点不能用
  26. for(i=1;i<=n;i++)
  27. {
  28. if(!vis[i])
  29. {
  30. for(j=0;j<num[i];j++)//对每一个点的儿子进行遍历覆盖
  31. {
  32. p[a[i][j]]=1;
  33. }
  34. }
  35. }
  36. for(i=1;i<=n;i++)
  37. {
  38. if(!p[i]&&!vis[i])//找到一个没有输出的点里面没人是他的爸爸就输出,hhhh这句话有点好笑
  39. {
  40. if(ans==0)
  41. {
  42. printf("%d",i);
  43. }
  44. else
  45. printf(" %d",i);
  46. vis[i]=1;//输出过了
  47. break;
  48. }
  49. }
  50. dfs(ans+1);//很好,下一个
  51. }
  52. int main()
  53. {
  54. int x,i,j,tot,sum;
  55. while(scanf("%d",&n)!=EOF)
  56. {
  57. tag=0;
  58. memset(vis,0,sizeof(vis));
  59. memset(num,0,sizeof(num));
  60. for(i=1;i<=n;i++)
  61. {
  62. while(scanf("%d",&x)&&x)
  63. {
  64. a[i][num[i]]=x;
  65. num[i]++;
  66. }
  67. }
  68. dfs(0);
  69. printf("\n");
  70. }
  71. }

发表评论

表情:
评论列表 (有 0 条评论,242人围观)

还没有评论,来说两句吧...

相关阅读

    相关 POJ 3321-Apple Tree【树状数组+DFS序】

    卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果。卡卡很喜欢苹果。树上有N个节点,卡卡给他们编号1到N,根的编号永远是1.每个节点上最多结一个苹果。卡卡想要了解某一个子树上一共

    相关 poj2367 拓扑排序入门

    先来一道拓扑排序的裸题吧!! 首先要知道拓扑排序的概念,拓扑排序就是,先找到入度为0的点,删去,同时把它的所有出度删去,再找新的入度为0的点,删去的点的顺序就是拓扑序

    相关 poj 1094 拓扑排序

    悲剧,这题错得好惨,首先这题题意就没仔细看清,误读题意。 读懂题意后又悲剧了,当不确定时还要判断是否有回路。 判断回路时又用了错误算法,思考不认真,当然知道可以用Floyd