• 【9010】家谱树


    Time Limit: 1 second
    Memory Limit: 128 MB

    【问题描述】

    有个人的家族很大,辈分关系很混乱,请你帮真理一下这种关系。 给出每个人的孩子的信息。 输出一个序列,使得每个人的后备都比那个人后列出。 

    【输入格式】

    第一行一个整数n(1<=n<=100),表示家族的人数。 接下来n行,第i行描述第i个的儿子。 每行最后是0表示描述完毕。

    【输出格式】

    输出一个序列,使得每个人的后辈都比那个人后列出。 如果有多解输出任意一解。

    Sample Input

    5
    0
    4 5 1 0
    1 0
    5 3 0
    3 0
    
    

    Sample Output

    2 4 5 3 1


    【题解】

    这是道拓扑排序的题。
    首先。对于第i行出现的整数。
    他们都是i的后代。
    于是给这些整数和i之间建立一条有向边。由这些整数指向i。这些整数的出度递增。
    然后,要记录这些整数和i之间有边。方便后续递减与已经输出的点相关的点的出度。
    每次找出度为0的点输出即可。

    【代码】

    #include <cstdio>
    #include <cstring>
    
    int n,w[101][101],chu[101],ans[101],num = 0;
    
    void input_data()
    {
    	memset(w,0,sizeof(w)); //记录和弹出的点相关的点的信息。 
    	scanf("%d",&n);
    	for (int i = 1;i <= n;i++)
    		{
    			int x;
    			scanf("%d",&x); //输入x  
    			while (x != 0) //如果不为0 就继续输入 
    				{
    					w[i][x] = 1; //记录i和x有联系 
    					chu[x] ++; //x->i的一条单向边 
    					scanf("%d",&x);	 //继续输入 
    				}
    		}
    }
    
    void get_ans()
    {
    	for (int i = 1;i <= n;i++) //肯定要输出n个数字的 
    		{
    			for (int j = 1;j <= n;j++) //找到出度为0 的点 
    				if (chu[j] == 0)
    					{
    						ans[++num] = j; //把它加入答案。 
    						chu[j] = -1; //同时把这个出度置为-1,下次就不会再找到这个点了. 
    						for (int k = 1;k <= n;k++) //找到和这个点有关的点 
    							if (w[j][k] == 1) //如果相连着去掉这条边同时和这个点有关的点的出度递减。 
    								{
    									w[j][k] = 0;
    									chu[k]--;	
    								}
    					}
    		}
    }
    
    void output_ans()
    {
    	for (int i = 1;i <= num-1;i++)
    		printf("%d ",ans[i]);
    	printf("%d
    ",ans[num]);	
    }
    
    int main()
    {
    	//freopen("F:\rush.txt","r",stdin);
    	input_data();
    	get_ans();
    	output_ans();
    	return 0;	
    }


  • 相关阅读:
    第六周总结
    《构建之法》读后感二
    移动端疫情展示
    第五周
    用python爬取疫情数据
    第四周
    疫情图表展示和时间查询
    wpf datagrid row height 行高自动计算使每行行高自适应文本
    c# 实现mysql事务
    c# 简单实现 插件模型 反射方式
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632398.html
Copyright © 2020-2023  润新知