【题解】历届试题 发现环⭐⭐ 【图中判环 经典问题】

    xiaoxiao2022-07-03  103

    历届试题 发现环

    小明的实验室有N台电脑,编号1~N。原本这N台电脑之间有N-1条数据链接相连,恰好构成一个树形网络。在树形网络上,任意两台电脑之间有唯一的路径相连。

    不过在最近一次维护网络时,管理员误操作使得某两台电脑之间增加了一条数据链接,于是网络中出现了环路。环路上的电脑由于两两之间不再是只有一条路径,使得这些电脑上的数据传输出现了BUG。

    为了恢复正常传输。小明需要找到所有在环路上的电脑,你能帮助他吗?

    Input

    第一行包含一个整数N。   以下N行每行两个整数a和b,表示a和b之间有一条数据链接相连。

    对于30%的数据,1 <= N <= 1000   对于100%的数据, 1 <= N <= 100000, 1 <= a, b <= N

    输入保证合法。

    Output

    按从小到大的顺序输出在环路上的电脑的编号,中间由一个空格分隔。

    Examples

    样例输入 5 1 2 3 1 2 4 2 5 5 3 样例输出 1 2 3 5

    Hint

    题意:

    题解:

    比较经典的图中判环问题, 通过DFS来搜, 储存每个节点的父节点, 发现有已访问的节点且不为当前节点父节点, 就说明出现了环, 顺着查找pre数组即可 因为只有一个环, 所以复杂度O(N)

    经验小结:

    #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <string> #include <stdlib.h> #include <vector> #include <queue> #include <cmath> #include <stack> #include <map> #include <set> using namespace std; #define ms(x, n) memset(x,n,sizeof(x)); typedef long long LL; const int inf = 1<<30; const LL maxn = 1e5+10; int N; vector<int> es[maxn], ans; bool vis[maxn]; int pre[maxn]; bool isEnd = false; void Dfs(int u){ vis[u] = true; for(int i = 0; i < es[u].size(); ++i){ if(isEnd) return; int v = es[u][i]; if(!vis[v]){ pre[v] = u; Dfs(v); } else if(pre[u] != v){ ans.push_back(v); while(v != u){ ans.push_back(u); u = pre[u]; } sort(ans.begin(), ans.end()); for(int i = 0; i < ans.size(); ++i) cout << ans[i] << " "; cout << endl; isEnd = true; return; } } } int main() { int a, b; cin >> N; for(int i = 1; i <= N; ++i){ cin >> a >> b; es[a].push_back(b), es[b].push_back(a); } ms(pre, -1); Dfs(1); return 0; }
    最新回复(0)