685. Redundant Connection II
https://leetcode.com/problems/redundant-connection-ii/description/
Last updated
Was this helpful?
https://leetcode.com/problems/redundant-connection-ii/description/
Last updated
Was this helpful?
有向图去掉一条边可以构成一棵树,问按照给定边顺序最早该去掉哪条。花花总结了三种情况:
Case1相当于无向图,用union find依次遍历并加入边,当发现当前边的两端已经在同一个连通分量时,返回当前边。
Case 2是一个结点有两个parent,需要去掉其中一条边。先遍历所有边,当有结点出现了两个parents时对应的两条边即答案候选。先选第二个出现的在图里删掉。在用UF以处理第一种方法,当发现环时且候选不为空时,把候选第一条边删掉 (Case 2.2);否则没检测到环,意味着它已经被删过了,对应Case 2.2。
/*
* @lc app=leetcode id=685 lang=cpp
*
* [685] Redundant Connection II
*
* https://leetcode.com/problems/redundant-connection-ii/description/
*
* algorithms
* Hard (31.08%)
* Likes: 519
* Dislikes: 165
* Total Accepted: 25.8K
* Total Submissions: 82.7K
* Testcase Example: '[[1,2],[1,3],[2,3]]'
*
*
* In this problem, a rooted tree is a directed graph such that, there is
* exactly one node (the root) for which all other nodes are descendants of
* this node, plus every node has exactly one parent, except for the root node
* which has no parents.
*
* The given input is a directed graph that started as a rooted tree with N
* nodes (with distinct values 1, 2, ..., N), with one additional directed edge
* added. The added edge has two different vertices chosen from 1 to N, and
* was not an edge that already existed.
*
* The resulting graph is given as a 2D-array of edges. Each element of edges
* is a pair [u, v] that represents a directed edge connecting nodes u and v,
* where u is a parent of child v.
*
* Return an edge that can be removed so that the resulting graph is a rooted
* tree of N nodes. If there are multiple answers, return the answer that
* occurs last in the given 2D-array.
* Example 1:
*
* Input: [[1,2], [1,3], [2,3]]
* Output: [2,3]
* Explanation: The given directed graph will be like this:
* 1
* / \
* v v
* 2-->3
*
*
* Example 2:
*
* Input: [[1,2], [2,3], [3,4], [4,1], [1,5]]
* Output: [4,1]
* Explanation: The given directed graph will be like this:
* 5 2
* ^ |
* | v
* 4
*
* Note:
* The size of the input 2D-array will be between 3 and 1000.
* Every integer represented in the 2D-array will be between 1 and N, where N
* is the size of the input array.
*
*/
class Solution {
public:
vector<int> findRedundantDirectedConnection(vector<vector<int>>& edges) {
const int N = edges.size();
vector<int> parents(N + 1, 0);
vector<int> roots(N + 1, 0);
vector<int> sizes(N + 1, 1);
vector<int> res, res2;
for (auto &edge : edges) {
const int u = edge[0], v = edge[1];
if (parents[v] > 0) {
res = {parents[v], v};
res2 = edge;
edge[0] = edge[1] = -1;
}
parents[v] = u;
}
const auto find = [](vector<int> &roots, int x) {
while (roots[x] != x) {
roots[x] = roots[roots[x]];
x = roots[x];
}
return x;
};
for (const auto &edge : edges) {
const int u = edge[0], v = edge[1];
if (u < 0 || v < 0) continue;
if (!roots[u]) roots[u] = u;
if (!roots[v]) roots[v] = v;
int pu = find(roots, u);
int pv = find(roots, v);
if (pu == pv) return res.empty() ? edge : res;
if (sizes[pv] > sizes[pu]) swap(pu, pv);
roots[pv] = pu;
sizes[pu] += sizes[pv];
}
return res2;
}
};