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\n",ans[num]);
}
int main()
{
//freopen("F:\\rush.txt","r",stdin);
input_data();
get_ans();
output_ans();
return 0;
}