b_lc_发现环(并查集+dfs / 拓扑排序)

小明的实验室有N台电脑,编号1~N。原本这N台电脑之间有N-1条数据链接相连,恰好构成一个树形网络。网络中出现了环路。
从小到大的顺序输出在环路上的电脑的编号(N<=100000)

方法一:并查集+dfs

思路
这题不用并查集找环的起点的话需要 O(n) 时间确定找,会t,这里用了并查集优化找环过程

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int n,m,st,ed,found,fa[N],vis[N];
vector<int> path, g[N];
int find(int u) {return fa[u]==u ? u : fa[u]=find(fa[u]);}
void merge(int a, int b) {
    fa[find(a)]=find(b);
}
void dfs(int u) {
    if (found) return;
    path.push_back(u);
    if (u==ed) {
        sort(path.begin(), path.end());
        for (int v : path) cout<<v<<' ';
        found=1;
        return;
    }
    for (int v : g[u]) if (!vis[v]) {
        vis[v]=1;
        dfs(v);
        vis[v]=0;
    }
    path.pop_back();
}
int main() {
    std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin>>n; for (int i=1; i<=n; i++) fa[i]=i;
    for (int i=0; i<n; i++) {
        int a,b; cin>>a>>b;
        g[a].push_back(b), g[b].push_back(a);
        if (find(a)!=find(b)) merge(a,b);
        else st=a,ed=b;
    }
    dfs(st);
    return 0;
}

方法二:拓扑排序

思路
从入度为 1 的结点开始拓扑排序,遍历到的点入度都减 1,剩下的入度为 2 的结点都是遍历不到的,也就是环上的结点(环上只有一个结点的入度 ≥ 2)

#include<bits/stdc++.h>
using namespace std;

const int N=1e5+50;
int n, s, e, vis[N], fa[N], in[N];
vector<vector<int>> g;

vector<int> bfs() {
    queue<int> q;
    for (int i=1; i<=n; i++) if (in[i]==1) q.push(i);
    while (!q.empty()) {
        int u=q.front(); q.pop();
        for (int v : g[u]) if (--in[v]==1) {
            q.push(v);
        }
    }
    vector<int> ans;
    for (int i=1; i<=n; i++) if (in[i]==2) ans.emplace_back(i);
    sort(ans.begin(), ans.end());
    return ans;
}
int main() {
    std::ios::sync_with_stdio(false);
    cin >> n;
    g.resize(n+1);

    for (int i=0; i<n; i++) {
        int a, b; cin >> a >> b;
        g[a].emplace_back(b), g[b].emplace_back(a);
        in[a]++, in[b]++;
    }
    vector<int> ans=bfs();
    for (int i=0; i<ans.size(); i++) cout << ans[i] << ' ';
    return 0;
}

复杂度分析

  • Time:O(n),
  • Space:O(n),
posted @ 2020-08-18 21:22  童年の波鞋  阅读(122)  评论(0编辑  收藏  举报