题目
我的思路:
- 题目没有给出源头,所以需要使用一个数组记录,再求出root节点
- 先用bfs求出树的最大深度,并记录最后一层的所有节点,再反推出最长链
我学到了什么(遇上的坑)
- 如果用algorithm的sort函数,默认是按字典升序排序的。
- 如果用deque记录最长链,头部插入比vector效率高,但是访问容易超时,所以还是用vector;
大概看了一下其他博客都是用DFS写的这道题,确实用DFS也更加容易,但我是个菜鸡,还只会BFS…
所以也贴上我的代码。
代码
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
class Node {
public:
vector<int> kids;
int parent;
int val;
Node() {
parent = -1;
}
};
int main() {
vector<vector<int>> lists;//记录最长链
int n = 0;
int root = 0;
cin >> n;
Node* tree = new Node[n];
int* check = new int[n];
for (int i = 0; i < n; i++)
{
int num = 0;
cin >> num;
tree[i].val = i;
for (int j = 0; j < num; j++)
{
int kid = 0;
cin >> kid;
check[kid] = 1;
tree[i].kids.push_back(kid);
tree[kid].parent = i;
}
}
//获取根节点
for (int i = 0; i < n; i++)
{
if (check[i] != 1) {
root = i;
break;
}
}
//层序遍历树,获取最大深度
queue<int> que;
que.push(root);
vector<int> last;
int count = 0;
while (!que.empty()) {
int size = que.size();
last.clear();
count++;
for (int i = 0; i < size; i++)
{
Node node = tree[que.front()];
que.pop();
int size_q = node.kids.size();
last.push_back(node.val);
for (int j = 0; j < size_q; j++)
{
que.push(node.kids[j]);
}
}
}
//从下而上获取最长链
lists.resize(last.size());
for (int i = 0; i < last.size(); i++)
{
lists[i].resize(count);
}
for (int i = 0; i < count; i++)
{
for (int m = 0; m < last.size(); m++)
{
//如果使用deque.push_front容易超时
lists[m][count - i - 1] = last[m];
last[m] = tree[last[m]].parent;
}
}
if (lists.size() != 1) {
sort(lists.begin(), lists.end());//默认按字典升序排序
}
cout << count << endl;
cout << root;
for (int i = 1; i < count; i++)
{
cout << " " << lists[0][i];
}
delete[] tree,check;
return 0;
}
拓展
如果将题目末尾规则反转,即输出最大序列的话,可以这样修改代码
//如果输出最大序列
class MyCompare {
public:
bool operator()(vector<int> a,vector<int> b) {
for (int i = 0; i < a.size(); i++)
{
if (a[i] != b[i]) {
if (a[i] > b[i]) return true;
else if (a[i] < b[i]) return false;
}
}
return false;
}
};
DFS解法
最近学了回溯,来更新一下DFS解法
#include<iostream>
#include<string>
#include<vector>
#include<set>
#include<algorithm>
using namespace std;
class Node {
public:
vector<int> kids;
Node() {
}
};
Node* tree;
vector<vector<int>> result;
vector<int> path;
void dfs(int root) {
if (tree[root].kids.size() == 0) {
if (!result.empty() && path.size() < result[result.size() - 1].size()) {
return;
}
else if (!result.empty() && path.size() > result[result.size() - 1].size()) { //找到更长链,清空当前结果集
result.clear();
}
result.push_back(path);
return;
}
for (int i = 0; i < tree[root].kids.size(); i++)
{
path.push_back(tree[root].kids[i]);
dfs(tree[root].kids[i]);
path.pop_back();
}
}
int main() {
int n = 0;
cin >> n;
int* count = new int[n];
tree = new Node[n];
int root = 0;
for (int i = 0; i < n; i++)
{
int num = 0;
cin >> num;
for (int j = 0; j < num; j++)
{
int index = 0;
cin >> index;
tree[i].kids.push_back(index);
count[index] = 1;
}
}
for (int i = 0; i < n; i++)
{
if (count[i] != 1) {
root = i;
break;
}
}
dfs(root);
sort(result.begin(), result.end());//默认排序字典序不要忘,否则超时
cout << result[0].size() + 1 << endl;
cout << root;
for (int i = 0; i < result[0].size(); i++)
{
cout << " " << result[0][i];
}
delete[] count;
delete[] tree;
return 0;
}