LeetCode 685. 冗余连接 II (并查集 + 树上乱搞)

29 篇文章 0 订阅
11 篇文章 0 订阅

题目链接

Solution

输入的边有N条,其中有一条为“附加边”,但我们不知道是哪条边。
但这条边的存在会使得原本的有根树出现严格一个环(不考虑方向)。
我们一边加边,一边将两端点用并查集合并,
当两端点在合并前就属于同一个并查集时,说明加上这条边后就会出现环
于是就找到了原图中唯一的环,我们用dfs将环上的点标记
最后倒序枚举输入的边,若当前边在环上,且删去后图中入度为0的点有且只有一个,那么就找到了答案

Code

class Solution {
public:
    int N, fa[1000 + 7], in[1000 + 7];
    int find(int x) {return x == fa[x] ? x:fa[x] = find(fa[x]);}

    vector<int>to[1000 + 7];
    int st, ed;
    bool vis[1000 + 7];
    bool dfs(int u,int f) {
        vis[u] = true;
        if(u == ed) return true;
        for(int i = 0;i < to[u].size();++i) {
            int v = to[u][i]; if(v == f) continue;
            if(dfs(v,u)) return true;
            vis[v] = false;
        } return false;
    }
    vector<int> findRedundantDirectedConnection(vector<vector<int>>& edges) {
        N = edges.size();
        vector<int>root;
        for(int i = 1;i <= N;++i) fa[i] = i;
        for(int i = 0;i < N;++i) {
            int u = edges[i][0], v = edges[i][1];
            in[v]++;
            int f1 = find(u), f2 = find(v);
            if(f1 == f2) {
                st = u, ed = v;
            } else {
                fa[f1] = f2;
                to[u].push_back(v); to[v].push_back(u); 
            }
        }
        for(int i = 1;i <= N;++i) if(in[i] == 0) root.push_back(i);
        //debug2(st,ed);
        dfs(st,st);
        vector<int>res;
        for(int i = N - 1;i>=0;--i) {
            int u = edges[i][0], v = edges[i][1];
            if(!vis[u] || !vis[v]) continue;
            --in[v];
            if(root.size() == 1 && in[v] == 0) continue;
            if(root.size() == 0 && in[v] != 0) continue;
            res.push_back(u), res.push_back(v);break;
        }
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值