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;
}
};