import java.util.*;
public class Main{
private static int[] father;
public static void main(String[] args){
Scanner in=new Scanner(System.in);
int n=in.nextInt();
father=new int[n+1];
init(father,n);
for(int i=0;i<n;i++){
int u=in.nextInt();
int v=in.nextInt();
join(u,v);
}
}
public static void init(int[] array,int n){
for(int i=1;i<=n;i++){
array[i]=i;
}
}
public static int find(int u){
if(u==father[u])return u;
else return find(father[u]);
}
public static void join(int u,int v){
int a=u;
int b=v;
u=find(u);
v=find(v);
if(u==v){
System.out.println(a+" "+b);
return;
}
father[v]=u;
}
}
冗余连接II
题目描述
有一种有向树,该树只有一个根节点,所有其他节点都是该根节点的后继。该树除了根节点之外的每一个节点都有且只有一个父节点,而根节点没有父节点。有向树拥有 n 个节点和 n - 1 条边。如图:
现在有一个有向图,有向图是在有向树中的两个没有直接链接的节点中间添加一条有向边。如图:
输入一个有向图,该图由一个有着 n 个节点(节点编号 从 1 到 n),n 条边,请返回一条可以删除的边,使得删除该条边之后该有向图可以被当作一颗有向树。
输入描述
第一行输入一个整数 N,表示有向图中节点和边的个数。
后续 N 行,每行输入两个整数 s 和 t,代表这是 s 节点连接并指向 t 节点的单向边
输出描述
输出一条可以删除的边,若有多条边可以删除,请输出标准输入中最后出现的一条边。
输入示例
3
1 2
1 3
2 3
输出示例
2 3
提示信息
在删除 2 3 后有向图可以变为一棵合法的有向树,所以输出 2 3
数据范围:
1 <= N <= 1000
思路:
1.首先统计入度为2的节点,指向这个节点的两条有向边一定有一条是多余的。
java复制代码
int[] indegree = new int[n + 1];
for (int i = 0; i < n; i++) {
int u = in.nextInt();
int v = in.nextInt();
edges.add(new int[] {u, v});
indegree[v]++;
}
public static void Circle(List<int[]> edges){
for(int i=0;i<edges.size();i++){
if (isSame(edges.get(i)[0], edges.get(i)[1]) == true)
System.out.println(edges.get(i)[0]+" "+ edges.get(i)[1]);
join(edges.get(i)[0], edges.get(i)[1]);
}
}
整体代码如下:
java复制代码
import java.util.*;
public class Main {
private static int[] father;
private static List<int[]> edges = new ArrayList<>();
private static List<int[]> list = new ArrayList<>();
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
father = new int[n + 1];
init(father, n);
int[] indegree = new int[n + 1];
for (int i = 0; i < n; i++) {
int u = in.nextInt();
int v = in.nextInt();
edges.add(new int[] {u, v});
indegree[v]++;
}
for (int i = 0; i < edges.size(); i++) {
if (indegree[edges.get(i)[1]] == 2) {
list.add(edges.get(i));
}
}
if (list.size()>0) {
edges.remove(list.get(1));
if (isLegal(edges) == true) {
System.out.println(list.get(1)[0] + " " + list.get(1)[1]);
} else {
System.out.println(list.get(0)[0] + " " + list.get(0)[1]);
}
}
else Circle(edges);
}
public static void Circle(List<int[]> edges){
for(int i=0;i<edges.size();i++){
if (isSame(edges.get(i)[0], edges.get(i)[1]) == true) System.out.println(edges.get(i)[0]+" "+ edges.get(i)[1]);
join(edges.get(i)[0], edges.get(i)[1]);
}
}
public static void init(int[] array, int n) {
for (int i = 1; i <= n; i++) {
array[i] = i;
}
}
public static boolean isLegal(List<int[]> edges) {
for (int i = 0; i < edges.size(); i++) {
if (isSame(edges.get(i)[0], edges.get(i)[1]) == true) return false;
join(edges.get(i)[0], edges.get(i)[1]);
}
return true;
}
public static int find(int u) {
if (u == father[u]) return u;
else return father[u] = find(father[u]);
}
public static void join(int u, int v) {
u = find(u);
v = find(v);
if (u == v) return;
father[v] = u;
}
public static boolean isSame(int u, int v) {
u = find(u);
v = find(v);
return u == v;
}
}