团体天梯练习 L2-031 深入虎穴

发布时间 2023-04-19 15:49:29作者: Amαdeus

L2-031 深入虎穴

著名的王牌间谍 007 需要执行一次任务,获取敌方的机密情报。已知情报藏在一个地下迷宫里,迷宫只有一个入口,里面有很多条通路,每条路通向一扇门。每一扇门背后或者是一个房间,或者又有很多条路,同样是每条路通向一扇门…… 他的手里有一张表格,是其他间谍帮他收集到的情报,他们记下了每扇门的编号,以及这扇门背后的每一条通路所到达的门的编号。007 发现不存在两条路通向同一扇门。

内线告诉他,情报就藏在迷宫的最深处。但是这个迷宫太大了,他需要你的帮助 —— 请编程帮他找出距离入口最远的那扇门。

输入格式:

输入首先在一行中给出正整数 \(N\)\(<10^{5}\) ),是门的数量。最后 \(N\) 行,第 \(i\) 行( \(1≤i≤N\) )按以下格式描述编号为 \(i\) 的那扇门背后能通向的门:

\(K\) \(D[1]\) \(D[2]\) ... \(D[K]\)

其中 \(K\) 是通道的数量,其后是每扇门的编号。

输出格式:

在一行中输出距离入口最远的那扇门的编号。题目保证这样的结果是唯一的。

输入样例:

13
3 2 3 4
2 5 6
1 7
1 8
1 9
0
2 11 10
1 13
0
0
1 12
0
0

输出样例:

12


解题思路

注意题中给出的条件“007 发现不存在两条路通向同一扇门”,那么很显然这是一个树的结构,所以要求的最远的点,只需要 \(BFS\) 求得最后一个出队的点即可。
但是,我们需要先找出树的 根节点 才能进行 \(BFS\)。定义一个数组 \(hasfa\) ,在处理关系时记录每个点是否有祖辈。构建完树之后,用一个循环找到没有祖辈的节点,那么此节点就是树的根节点。

/*   一切都是命运石之门的选择  El Psy Kongroo  */
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<cmath>
#include<functional>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<int, pii> piii;
typedef pair<double, double> pdd;
typedef pair<string, int> psi;
typedef __int128 int128;
#define PI acos(-1.0)
#define x first
#define y second
//int dx[4] = {1, -1, 0, 0};
//int dy[4] = {0, 0, 1, -1};
const int inf = 0x3f3f3f3f, mod = 1e9 + 7;


const int N = 1e5 + 10;
int h[N], e[N], ne[N], idx;
bool hasfa[N];
int n, root, res;

void add(int a, int b){
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}

void bfs(){
    queue<int> q; q.push(root);

    while(!q.empty()){
        int u = q.front();
        q.pop();

        res = u;    //记录出队的点

        for(int i = h[u]; ~i; i = ne[i]){
            int v = e[i];
            q.push(v);
        }
    }
    //退出循环时最后一个出队的点就是最远的点
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    memset(h, -1, sizeof(h));
    cin >> n;
    for(int u = 1; u <= n; u ++ ){
        int k; cin >> k;
        while(k -- ){
            int v; cin >> v;
            add(u, v);
            hasfa[v] = true;
        }
    }

    root = 1;
    while(hasfa[root]) root ++ ;

    bfs();

    cout << res << endl;

    return 0;
}