1. 程式人生 > 其它 >acwing \1191. 家譜樹

acwing \1191. 家譜樹

目錄

題目傳送門

題目描述

有個人的家族很大,輩分關係很混亂,請你幫整理一下這種關係。

給出每個人的孩子的資訊。

輸出一個序列,使得每個人的孩子都比那個人後列出。

輸入格式

第 11 行一個整數 nn,表示家族的人數;

接下來 nn 行,第 ii 行描述第 ii 個人的孩子;

每行最後是 00 表示描述完畢。

每個人的編號從 11 到 nn。

輸出格式

輸出一個序列,使得每個人的孩子都比那個人後列出;

資料保證一定有解,如果有多解輸出任意一解。

資料範圍

1≤n≤1001≤n≤100

輸入樣例:

5
0
4 5 1 0
1 0
5 3 0
3 0

輸出樣例:

2 4 5 3 1

拓撲排序模板題

分析

topo排序,記錄排序順序即可

程式碼

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue> 
using namespace std;
const int N = 110;
int n;
int deg[N]; // 入度 
vector<int> h[N];
int res[N];
int cnt = 0;
void add(int a, int b)
{
	// a->b
	h[a].push_back(b);
}
void topo()
{
	queue<int> q;
	for(int i = 1; i <= n; i++)
		if(!deg[i]) q.push(i), res[cnt++] = i;
		
	while(q.size())
	{
		int t = q.front();
		q.pop();
		
		for(int i = 0; i < h[t].size(); i++)
		{
			int j = h[t][i];
			deg[j]--;
			
			if(!deg[j]) q.push(j), res[cnt++] = j;
		}
	}
}

int main()
{
	scanf("%d", &n);
	for(int i = 1; i <= n; i++)
	{
		while(true)
		{
			int x;
			scanf("%d", &x);
			if(!x) break;
			
			add(i, x);
			deg[x]++;
		}
	}
//	printf("%d", res);
	topo();
	
	for(int i = 0; i < cnt; i++) printf("%d ", res[i]);
	return 0;
} 

時間複雜度

參考文章