标签:队列 namespace assm member system you first real out
5 0 4 5 1 0 1 0 5 3 0 3 0Sample Output
2 4 5 3 1
火星人的血缘关系体系已经够混乱的了。事实上,火星人在他们想要的时间和地点发芽。他们以不同的群体聚集在一起,这样火星人可以有一个父母和十个父母。一百个孩子不会让任何人感到惊讶。
火星人已经习惯了这一点,他们的生活方式对他们来说似乎很自然。 在行星理事会,混乱的系谱系统导致了一些尴尬。在那里遇到最有价值的火星人,因此为了在所有的讨论中不冒犯任何人,它首
先被用来让老火星人发言,而不是让年轻的火星人发言,也只是让最年轻的没有孩子的评估者发言。然而,维持这一秩序确实不是一项微不足道的任务。火星人并不总是认识他所有的父母(关于他的
祖父母也没什么好说的!)。但是如果由于一个错误先说一个孙子,而只是比他年轻时显得曾祖父,这是一个真正的丑闻。 你的任务是编写一个程序,一劳永逸地确定一个秩序,保证安理会的每个成
员比他的每一个后代发言更早。
投入 标准输入的第一行只包含一个数字N,1 < = N < = 100——火星行星理事会的一些成员。根据几个世纪以来的传统,委员会的成员用从1到N的自然数来计数。此外,正好有N条线,而且,第I条线
包含第I个成员的孩子的列表。子列表是以任意顺序由空格分隔的一系列子序列号。孩子列表可能为空。列表(即使是空的)以0结尾。
输出 标准输出应该在其唯一的一行中包含一系列由空格分隔的扬声器号码。如果几个序列满足问题的条件,您将把它们中的任何一个写入标准输出。至少有一个这样的序列总是存在的。
样本值输入 5 0 4 5 1 0 1 0 5 3 0 3 0
抽样输出 2 4 5 3 1
#include<stdio.h>
#include<iostream>
using namespace std;
int num_edge=0,head[10001],ht[10001],que[10001],hed,tail;
struct Edge
{
int to,next;
}edge[100001];
void add_edge(int from,int to)
{
edge[++num_edge].next=head[from];
edge[num_edge].to=to;
head[from]=num_edge;
}
int main()
{
int a,n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
while(1)
{
scanf("%d",&a);
if(a==0) break;
else {add_edge(i,a);ht[a]++; //ht数组记录入度;
}
}
}
hed=0;tail=0;
for(int i=1;i<=n;i++)
{
if(ht[i]==0)
{
tail++;que[tail]=i; //入度为零加入队列
}
}
while(hed<tail)
{
hed++;
for(int i=head[que[hed]];i!=0;i=edge[i].next)
{ ht[edge[i].to]--; //队首出队后接下来的点的入度就减少一
if(ht[edge[i].to]==0)
{tail++;que[tail]=edge[i].to;//入度为零入队
}
}
}
for(int i=1;i<=n;i++) printf("%d ",que[i]);
return 0;
}
拓扑排序例题
所谓一张有向无环图(DAG)的拓扑序列,即为一个点的序列,满足对任意一条边(u,v),u都出现在v的前面。
求解拓扑序列的方法叫做『拓扑排序』。
求法:首先,辈分最高的人肯定入度为0。
找出图中所有入度为0的点,放入一个队列中。(顺序无所谓)
用类似BFS的方法,我们依次从队首取出点来,先输出到最后的答案序列,然后遍历从当前点u发出的所有边(u, v)。对v入度减一。如果某个v的入度减为0了,这个v就变成了目前辈分最高的状态,将其由队尾插入。
标签:队列 namespace assm member system you first real out
原文地址:https://www.cnblogs.com/xcsj/p/11961029.html