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;
}
分类:
图论
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」