• 1579. 保证图可完全遍历 并查集


    Alice 和 Bob 共有一个无向图,其中包含 n 个节点和 3  种类型的边:

    类型 1:只能由 Alice 遍历。
    类型 2:只能由 Bob 遍历。
    类型 3:Alice 和 Bob 都可以遍历。
    给你一个数组 edges ,其中 edges[i] = [typei, ui, vi] 表示节点 ui 和 vi 之间存在类型为 typei 的双向边。请你在保证图仍能够被 Alice和 Bob 完全遍历的前提下,找出可以删除的最大边数。如果从任何节点开始,Alice 和 Bob 都可以到达所有其他节点,则认为图是可以完全遍历的。

    返回可以删除的最大边数,如果 Alice 和 Bob 无法完全遍历图,则返回 -1 。

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/remove-max-number-of-edges-to-keep-graph-fully-traversable
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    注意实例化两个并查集实例,来进行操作。

    class UnionFind {
    public:
        unordered_map <int, int> fa;
        unordered_map <int, int> rank;
        int setCount;
        
        UnionFind(int n): setCount(n) {}
    
        int find(int x) {
            if (!fa.count(x)) {
                fa[x] = x;
                rank[x] = 1;
            }
            return fa[x] == x ? fa[x] : fa[x] = find(fa[x]);
        }
    
        bool same(int x, int y) {
            return find(x) == find(y);
        }
    
        bool merge(int x, int y) {
            int xx = find(x);
            int yy = find(y);
            if (same(xx, yy)) {
                return false;
            }
            if (rank[xx] < rank[yy]) {
                swap(xx, yy);
            }
            rank[xx] += rank[yy];
            fa[yy] = xx;
            setCount--;
            return true;
        }
    };
    
    class Solution {
    public:
        int maxNumEdgesToRemove(int n, vector<vector<int>>& edges) {
            int ans = 0;
            UnionFind ufA(n), ufB(n);
    
            for (auto& edge : edges) {
                edge[1]--;
                edge[2]--;
            }
    
            for (auto edge : edges) {
                if (edge[0] == 3) {
                    int u = edge[1];
                    int v = edge[2];
                    if (!ufA.merge(u, v)) {
                        ans++;
                    }
                    else {
                        ufB.merge(u, v);
                    }
                }
            }
    
            for (auto edge : edges) {
                int u = edge[1];
                int v = edge[2];
                if (edge[0] == 1) {
                    if (!ufA.merge(u, v)) {
                        ans++;
                    }
                }
                else
                if (edge[0] == 2) {
                    if (!ufB.merge(u, v)) {
                        ans++;
                    }
                }
            }
    
            if (ufA.setCount != 1 || ufB.setCount != 1) {
                return -1;
            }
            return ans;
        }
    };
    
  • 相关阅读:
    c# 一段生成6位不重复的随机数字码存8万个
    element ui 踩坑记
    Vue node.js 踩坑记
    javascript 异步回调链式调用 promise
    css 盒模型
    vue node.js 引入 linq
    Vue VsCode 项目 launch.json 文件
    node.js 基本语法识记
    Vue 2.0 入门示例识记
    在Windows系统中建立一个隐藏的帐户(在不登录界面显示)
  • 原文地址:https://www.cnblogs.com/xgbt/p/14337585.html
Copyright © 2020-2023  润新知