浏览器标题切换
浏览器标题切换end

POJ2367 - Genealogical tree - 拓扑排序模板题

题意

第一行一个5,代表1-5五个元素,每一行以0结束说明该行输入结束,往下走,第一行代表1的儿子没有,第二行代表2的儿子是4、5、1,第三行代表3的儿子是1,第四行代表4的儿子是5、3,第五行代表5的儿子是3;从长辈到晚辈依次输出。

思路

拓扑排序模板题。这一题英文看不懂,翻译了发现我,,中文也看不懂,还是别人和我讲的题意。之前已经看过拓扑排序,这也是这一周新学的知识点,做了一道简单入门的拓扑题。但是在昨天周赛上,不仅没写出来,而且数组开的也有问题,思路是没错,但是代码实现的过程偏了很多,希望多多反思自己学习效率上的问题以及思维逻辑方式上的问题。

AC代码

#include<stdio.h>
#include<string.h>

//需要开三个数组
int a;//输入
int dis[110][110];//标记相关的
int r[110];//每一个元素的入度
int ans[110];//存最后输入的答案

int main()
{
    int n,i,j;
    while(~scanf("%d",&n))//n行,n个元素
    {
      //  memset(a,0,sizeof(a));
        memset(dis,0,sizeof(dis));
        memset(r,0,sizeof(r));
        memset(r,0,sizeof(r));

        for(i=1;i<=n;i++)//控制行数
        {
            for(j=1;;j++)
            {
             //   scanf("%d",&a[j]);
                scanf("%d",&a);
                if(a==0)
                    break;
                if(dis[i][a]==0)//如果这条边之前没有联系
                {
                    dis[i][a]=1;//建立联系
                    r[a]++;//入度++,有了联系之后才将后面对应的点入度++
                }

            }
        }
        int b;//用来记录结点
        int k=0;
        for(i=1;i<=n;i++)//n行
        {
            for(j=1;j<=n;j++)
            {
                if(r[j]==0)//如果入度为0
                {
                    r[j]--;//入度--,让它入度为负数
                    ans[k++]=j;//存入结果中
                    b=j;//记录结点
                    break;
                }
            }
            //找到入度为0的数之后,再找和它相关的边删除
            //并且和它相关的那条边对应的元素入度--
            for(j=1;j<=n;j++)//通过循环找到所有相关的边
            {
                if(dis[b][j]==1)//找到对应的边
                {
                    dis[b][j]=0;
                    r[j]--;
                }
            }
        }
        for(i=0;i<k-1;i++)
            printf("%d ",ans[i]);
        printf("%d\n",ans[k-1]);
    }
    return 0;
}
posted @ 2019-05-26 13:23  抓水母的派大星  阅读(124)  评论(0编辑  收藏  举报