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; }