玖雨y的算法刷题记录day09——图论
- 题目链接:冗余连接II
- 题目思路:在day08冗余连接一题的基础上,这题将无向图改为有向图,整体还是通过并查集来实现的,但相对要复杂一些,因为在处理无向图时我们仅需要考虑删除使树构成环的一条边,而在有向图中,我们可能有多条侯选边,需要从中作出选择。具体可参考:冗余连接II思路
import java.util.*;
class Main {
private static int[] father;
private static void init() {
for (int i = 0; i < father.length; i++) {
father[i] = i;
}
}
private static boolean isSame(int x, int y) {
int fx = find(x);
int fy = find(y);
return fx == fy;
}
private static int find(int u) {
if (u == father[u]) return u;
return father[u] = find(father[u]);
}
private static void join(int u, int v) {
u = find(u);
v = find(v);
if (u == v) return;
father[u] = v;
}
private static boolean isTreeAfterRemoveEdge(List<int[]> edges, int[] removeEdge) {
init();
for (int[] edge : edges) {
if (edge[0] == removeEdge[0] && edge[1] == removeEdge[1]) continue;
if (!isSame(edge[0], edge[1])) join(edge[0], edge[1]);
else return false;
}
return true;
}
private static void getRemoveEdge(List<int[]> edges) {
init();
for (int[] edge : edges) {
if (!isSame(edge[0], edge[1])) {
join(edge[0], edge[1]);
} else {
System.out.println(edge[0] + " " + edge[1]);
return;
}
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
List<int[]> edges = new ArrayList<>();
int[] inDegree = new int[n + 1];
father = new int[n + 1];
while (n-- != 0) {
int s = sc.nextInt();
int t = sc.nextInt();
inDegree[t]++;
edges.add(new int[]{s, t});
}
LinkedList<int[]> twoDegreeEdge = new LinkedList<>();
for (int[] edge : edges) {
if (inDegree[edge[1]] == 2) twoDegreeEdge.addFirst(edge);
}
if (!twoDegreeEdge.isEmpty()) {
if (isTreeAfterRemoveEdge(edges, twoDegreeEdge.get(0))) {
System.out.println(twoDegreeEdge.get(0)[0] + " " + twoDegreeEdge.get(0)[1]);
} else {
System.out.println(twoDegreeEdge.get(1)[0] + " " + twoDegreeEdge.get(1)[1]);
}
return;
}
getRemoveEdge(edges);
}
}