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 。 示例 1: 输入:n = 4, edges = [[3,1,2],[3,2,3],[1,1,3],[1,2,4],[1,1,2],[2,3,4]] 输出:2 解释:如果删除 [1,1,2] 和 [1,1,3] 这两条边,Alice 和 Bob
仍然可以完全遍历这个图。再删除任何其他的边都无法保证图可以完全遍历。
所以可以删除的最大边数是 2 。 示例 2: 输入:n = 4, edges = [[3,1,2],[3,2,3],[1,1,4],[2,1,4]] 输出:0 解释:注意,删除任何一条边都会使 Alice 和 Bob 无法完全遍历这个图。 示例 3: 输入:n = 4, edges = [[3,2,3],[1,1,2],[2,3,4]] 输出:-1 解释:在当前图中,Alice 无法从其他节点到达节点 4 。类似地,Bob 也不能达到节点 1 。因此,图无法完全遍历。 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/remove-max-number-of-edges-to-keep-graph-fully-traversable 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
1 // 并查集模板 2 3 class UnionFind{ 4 public: 5 vector<int> parent; 6 vector<int> size; 7 int n; 8 //当前联通分量数目 9 int setCount; 10 11 public: 12 UnionFind(int _n):n(_n),setCount(_n),parent(_n),size(_n,1){ 13 iota(parent.begin(), parent.end(), 0); 14 } 15 16 int findset(int x){ 17 return parent[x] == x ? x : parent[x] = findset(parent[x]); 18 } 19 20 bool unite(int x, int y) 21 { 22 x = findset(x); 23 y = findset(y); 24 if(x == y) 25 { 26 return false; 27 } 28 if(size[x] < size[y]) 29 { 30 swap(x,y); 31 } 32 parent[y] = x; 33 size[x] += size[y]; 34 --setCount; 35 return true; 36 } 37 38 bool connected(int x, int y) 39 { 40 x = findset(x); 41 y = findset(y); 42 return x == y; 43 } 44 }; 45 46 47 class Solution { 48 public: 49 int maxNumEdgesToRemove(int n, vector<vector<int>>& edges) { 50 UnionFind ufa(n), ufb(n); 51 int ans = 0; 52 53 //结点编号改为从0开始 54 for(auto & edge:edges) 55 { 56 --edge[1]; 57 --edge[2]; 58 } 59 60 //公共边 61 for(const auto& edge:edges) 62 { 63 if(edge[0]==3) 64 { 65 if(!ufa.unite(edge[1], edge[2])) 66 { 67 ++ans; 68 } 69 else 70 { 71 ufb.unite(edge[1], edge[2]); 72 } 73 } 74 } 75 76 //独占边 77 for(const auto& edge: edges) 78 { 79 if(edge[0] == 1) 80 { 81 //Alice 独占边 82 if(!ufa.unite(edge[1], edge[2])) 83 { 84 ++ans; 85 } 86 } 87 else if (edge[0]==2) 88 { 89 //Bob 独占边 90 if(!ufb.unite(edge[1], edge[2])) 91 { 92 ++ans; 93 } 94 } 95 } 96 97 if(ufa.setCount != 1 || ufb.setCount != 1) 98 { 99 return -1; 100 } 101 return ans; 102 } 103 };