day 54 图论part6

文章目录

  • [108. 多余的边](#108. 多余的边)
  • [109. 多余的边II](#109. 多余的边II)

108. 多余的边

无向图,直接用并查集判断是否成环就可以。

java 复制代码
import java.util.Scanner;

public class Main {
    private static int[] father;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int pointNum = scanner.nextInt();
        father = new int[pointNum + 1];
        init();
        for (int i = 0; i < pointNum; i++) {
            join(scanner.nextInt(), scanner.nextInt());
        }
    }

    /**
     * 并查集初始化
     */
    private static void init() {
        for (int i = 1; i < father.length; i++) {
            // 让每个元素指向自己
            father[i] = i;
        }
    }

    /**
     * 并查集寻根
     *
     * @param u
     * @return
     */
    private static int find(int u) {
        // 判断 u 是否等于自己,如果是的话,直接返回自己
        // 如果不等于自己,就寻找根,寻找的时候,反复进行路径压缩
        return u == father[u] ? u : (father[u] = find(father[u]));
    }

    /**
     * 判断 u 和 v 是否同根
     *
     * @param u
     * @param v
     * @return
     */
    private static boolean isSame(int u, int v) {
        return find(u) == find(v);
    }

    /**
     * 添加 边 到并查集,v 指向 u
     *
     * @param u
     * @param v
     */
    private static void join(int u, int v) {
        // --if-- 如果两个点已经同根,说明他们的信息已经存储到并查集中了,直接返回即可
        // 寻找u的根
        int uRoot = find(u);
        // 寻找v的根
        int vRoot = find(v);
        if (uRoot == vRoot) {
            // --if-- 如果u,v的根相同,说明两者已经连接了,直接输出
            System.out.println(u + " " + v);
            return;
        }
        // --if-- 将信息添加到并查集
        father[vRoot] = uRoot;
    }

}

109. 多余的边II

有向图,一共有三种情况,图中存在入度为2的节点,需要删除一条边,但是删除后要保证不成环,另外一种情况就是成环,没有节点入度为2。

java 复制代码
import java.util.*;

class Main {
    public static int N;
    static DisJoint disjoint;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        N = sc.nextInt();
        disjoint = new DisJoint(N + 1);
         List<Edge> edges = new ArrayList<>();
         int[] indegree = new int[N + 1];

         for (int i = 0; i < N; i++) {
            int s = sc.nextInt();
            int t = sc.nextInt();
            Edge edge = new Edge(s, t);
            edges.add(edge);
            indegree[t]++;
         }
         List<Integer> vec = new ArrayList<>();
         for (int i = 0; i < N; i++) {
            if (indegree[edges.get(i).t] == 2) {
                vec.add(i);
            }
         }
         if (vec.size() > 0) {
            if (isTreeAfterDelete(edges, vec.get(1))) {
                System.out.println(edges.get(vec.get(1)).s + " " + edges.get(vec.get(1)).t);
            }
            else {
                System.out.println(edges.get(vec.get(0)).s + " " + edges.get(vec.get(0)).t);
            }
            return;
         }
         for (int i = 0; i < N; i++) {
            if (disjoint.isSame(edges.get(i).s, edges.get(i).t)) {
                System.out.println(edges.get(i).s + " " + edges.get(i).t);
            }
            else {
                disjoint.join(edges.get(i).s, edges.get(i).t);
            }
         }
    }


    public static boolean isTreeAfterDelete(List<Edge> edges, Integer v) {
        disjoint = new DisJoint(N + 1);
        for (int i =0; i < N; i++) {
            if (i == v) {
                continue;
            }
            if (disjoint.isSame(edges.get(i).s, edges.get(i).t)) {
                return false;
            }
            else {
                disjoint.join(edges.get(i).s, edges.get(i).t);
            }
        }
        return true;
    }
}

class Edge {
    int s;
    int t;
    public Edge(int s, int t) {
        this.s = s;
        this.t = t;
    }
}
class DisJoint {
    private int[] father;

    public DisJoint(int N) {
        father = new int[N + 1];
        for (int i = 0; i < N; i ++) {
            father[i] = i;
        }
    }
    public int find(int n) {
        return father[n] == n ? n : (father[n] = find(father[n]));
    }
    public void join(int n, int m) {
        n = find(n);
        m = find(m);
        if (n == m) {
            return;
        }
        father[n] = m;
    }
    public boolean isSame(int n, int m) {
        n = find(n);
        m = find(m);
        return n == m;
    }

    
}
相关推荐
m0_74883949几秒前
R包grafify:简单操作实现高效统计绘图
开发语言·r语言
梓䈑1 分钟前
【算法题攻略】模拟
c++·算法
BIG_PEI2 分钟前
检查并安装Redis
java
大貔貅喝啤酒4 分钟前
基于Windows下载安装Android Studio 3.3.2版本教程(2026详细图文版)
android·java·windows·android studio
Evand J4 分钟前
【课题推荐与代码介绍】卡尔曼滤波器正反向估计算法原理与MATLAB实现
开发语言·算法·matlab
奋斗的小方6 分钟前
Java基础篇09:项目实战
java·开发语言
海兰7 分钟前
【第21篇-续】graph-Stream-Node改造为适配openAI模型示例
java·人工智能·spring boot·spring·spring ai
DFT计算杂谈7 分钟前
VASP新手入门: IVDW 色散修正参数
linux·运维·服务器·python·算法
vKd0Ff21L9 分钟前
如何在Dev-C++中设置TDM-GCC为默认编译器第九十一篇
java·jvm·c++
武子康11 分钟前
Java-221 RocketMQ 消息存储核心原理:CommitLog、ConsumerQueue、IndexFile 与消息过滤机制
java·大数据·分布式·消息队列·rabbitmq·rocketmq·java-rocketmq