某个国家有N个城市,编号0 至 N-1,他们之间用N - 1条道路连接,道路是双向行驶的,沿着道路你可以到达任何一个城市。你有一个旅行计划,这个计划是从编号K的城市出发,每天到达一个你没有去过的城市,并且旅途中经过的没有去过的城市尽可能的多(如果有2条路线,经过的没有去过的城市同样多,优先考虑编号最小的城市),直到所有城市都观光过一遍。现在给出城市之间的交通图T,以及出发地点K,你来设计一个旅行计划,满足上面的条件。例如:
(K = 2)
第1天 从2到0 (城市 1 和 0 变成去过的)
第2天 从0到6 (城市 4 和 6 变成去过的)
第3天 从6到3 (城市 3 变成去过的)
第4天 从3到5 (城市 5 变成去过的)
上图的输入数据为:0 1 2 2 1 4。共7个节点,除节点0之外,共6行数据。
第1个数0表示1到0有1条道路。
第2个数1表示2到1有1条道路。
Input
第1行:2个数N,K(1 <= N <= 50000, 0 <= K <= N - 1)
第2 - N + 1行:每行一个数,表示节点之间的道路。
Output
输出旅行的路线图,即每天到达的城市编号。
Input示例
7 2
0
1
2
2
1
4
Output示例
2
0
6
3
5
思路:
树形DP,依次找到叶子节点。将它们根据规则排序。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int MAXN = 1e5 + 10;
struct Node
{
int to, prev;
} edge[MAXN];
int tot = 0;
int head[MAXN], deep[MAXN];
void add(int u, int v)
{
tot++;
edge[tot].to = v;
edge[tot].prev = head[u];
head[u] = tot;
}
struct Node2
{
int num, depth, cnt;
Node2(int n, int d, int c = 0) : num(n), depth(d), cnt(c) {}
bool operator < (const Node2 &b) const
{
if (depth == b.depth)
{
return num < b.num;
}
return depth > b.depth;
}
};
vector<Node2> vn2;
int pre[MAXN];
void dfs(int x, int pr)
{
pre[x] = pr;
bool flag = false;
for (int i = head[x]; i > 0; i = edge[i].prev)
{
int v = edge[i].to;
if (v == pr)
{
continue;
}
else
{
flag = true;
}
deep[v] = deep[x] + 1;
dfs(v, x);
}
if (!flag)
{
vn2.push_back(Node2(x, deep[x]));
}
}
bool cmp(Node2 a, Node2 b)
{
if (a.cnt == b.cnt)
{
return a.num < b.num;
}
return a.cnt > b.cnt;
}
bool vis[MAXN];
int main()
{
int n, k;
cin >> n >> k;
int v;
for (int i = 1; i < n; i++)
{
cin >> v;
add(v, i);
add(i, v);
}
deep[k] = 1;
vis[k] = true;
dfs(k, -1);
sort(vn2.begin(), vn2.end());
for (int i = 0; i < vn2.size(); i++)
{
Node2 leaf = vn2[i];
int num = leaf.num;
int cnt = 0;
while (num != -1)
{
if (!vis[num])
{
cnt++;
vis[num] = true;
}
else
{
break;
}
num = pre[num];
}
vn2[i].cnt = cnt;
}
cout << k << endl;
sort(vn2.begin(), vn2.end(), cmp);
for (int i = 0; i < vn2.size(); i++)
{
if (vn2[i].cnt)
{
cout << vn2[i].num << endl;
}
}
return 0;
}