DFS+打印路径+最小字典序
思路:
搜索策略:从根节点往下搜索,对非根节点搜索无意义,还会超时。只要对所有一个节点的所有子节点按照升序排序,那么搜索到的第一个长度最长的路径就是答案。记录路径:使用一个记录父节点(前驱节点)的数组,这样只要记录最长路径的末尾结点即可反推回整条路径
AC代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 100010;
vector<int> v[N], path;
int last, depth, root;
int n, pre[N];
void dfs(int val, int u) //节点值为val,第u层
{
if(u > depth) //如果路径长度增长,修正尾节点和深度(长度)
{
depth = u;
last = val;
}
for(int i = 0; i < v[val].size(); i ++ )
dfs(v[val][i], u + 1);
}
int main()
{
cin >> n;
for(int i = 0; i < n; i ++ ) pre[i] = -1;
for(int i = 0; i < n; i ++ )
{
int k; cin >> k;
for(int j = 0; j < k; j ++ )
{
int x; cin >> x;
pre[x] = i;
v[i].push_back(x);
}
sort(v[i].begin(), v[i].end()); //对所有子节点排序
}
for(int i = 0; i < n; i ++ )
if(pre[i] == -1)
{
root = i; break;
}
dfs(root, 1);
while(last != -1) //逆推路径
{
path.push_back(last);
last = pre[last];
}
cout << depth << endl;
reverse(path.begin(), path.end());
for(int i = 0; i < path.size(); i ++ )
{
cout << path[i];
if(i != path.size() - 1) cout << " ";
}
return 0;
}