1. 程式人生 > >【HihoCoder - 1851】D級上司 (樹形圖,dfs)

【HihoCoder - 1851】D級上司 (樹形圖,dfs)

題幹:

H公司一共有N名員工,編號為1~N,其中CEO的編號是1。除了CEO之外,每名員工都恰好有唯一的直接上司;N名員工形成了一個樹形結構。  

我們定義X的1級上司是他的直接上司,2級上司是他上司的上司,以此類推……  

請你找出每名員工的D級上司是誰。

Input

第一行包含2個整數N和D。  

以下N-1行每行包含一個整數,依次代表編號是2-N的員工的直接上司的編號。  

對於50%的資料,1 ≤ N, D ≤ 10000  

對於100%的資料,1 ≤ N, D ≤ 100000

Output

依次輸出1~N的D級上司的編號,每個一行。如果某員工沒有D級上司,輸出-1。

Sample Input

5 2   
1  
1  
3  
3

Sample Output

-1  
-1  
-1  
1  
1

解題報告:

  開一個數組記錄dfs的過程中走過的節點,跟走迷宮差不多啊只不過網格圖換成了樹形圖。。

AC程式碼:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 2e5 + 5;
vector<int> vv[MAX];
int n,d;
int ans[MAX],dep[MAX];
void dfs(int cur,int root,int deep) {
	dep[deep] = cur;
	if(deep - d >= 0) ans[cur] = dep[deep-d];
	int up = vv[cur].size();
	for(int i = 0; i<up; i++) {
		int v = vv[cur][i];
		if(v == root) continue;
		dfs(v,cur,deep+1);
	}
} 
int main()
{
	memset(ans,-1,sizeof ans);
	cin>>n>>d;
	for(int i = 2,x; i<=n; i++) {
		scanf("%d",&x);
		vv[x].pb(i);vv[i].pb(x);
	}
	dfs(1,-1,0);
	for(int i = 1; i<=n; i++) {
		printf("%d\n",ans[i]);
	} 
	return 0 ;
 }

總結:

   這題其實應該加單向邊但是雙向邊也可以AC,,我感覺原因就在於是個樹形圖,又因為是從根節點開始搜的所以每次搜到的邊都是上級搜到下級的邊,這可以算是個樹形圖的一個小結論了,其實也很常用,因為貌似所有的樹形圖都可以這樣去使用雙向邊貌似還沒出過錯。