#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
using namespace std;
const int N = 10010;
int h[N], e[N * 2], ne[N * 2], vis[N];
int n, idx, tot;
vector <int> tmp, ans;
void add (int a, int b) //在节点a后插入b
{
e[idx] = b; ne[idx] = h[a]; h[a] = idx ++;
}
void dfs (int u, int sum) //爆搜,u是当前节点,sum是当前长度
{
if (sum > tot) //如果当前长度大于最大值,更新答案
{
tot = sum;
ans = tmp;
}
//如果当前长度等于最大值,要取序列最小
/*vector是可以直接比较大小的,比较两个vector上的, 每个位置上的字母 ,当发现不同的且字典序小的,拥有该字母的vector判定为小。
*/
else if (sum == tot)
{
if (tmp < ans)
ans = tmp; //取序列小的答案
}
for (int i = h[u]; i != -1; i = ne[i])
{
int j = e[i];
tmp.push_back (j); //当前路径
dfs (j, sum + 1); //搜索相邻节点j
tmp.pop_back (); //回溯
}
}
int main ()
{
memset (h, -1, sizeof h);
cin >> n;
for (int i = 0; i < n; i ++)
{
int k; cin >> k;
//边读入,边建树
while (k --)
{
int x; cin >> x;
add (i, x);
vis[x] = 1; //vis数组用于找根节点,根节点vis为0
}
}
int root;
for (int i= 0; i < n; i ++) //寻找根节点
if (!vis[i])
root = i;
dfs (root, 1);
cout << tot << "\n";
cout << root; //root没有存在ans里,要提前输出
for (int i = 0; i < (int)ans.size (); i ++)
cout << " " << ans[i];
return 0;
}
L2-038 病毒溯源(详细注释) (25 分)
最新推荐文章于 2024-04-03 23:10:18 发布