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

    
}
相关推荐
yoyo_zzm4 小时前
Laravel6.x新特性全解析
java·spring boot·后端
AIFarmer4 小时前
【无标题】
开发语言·c++·算法
Nick_zcy4 小时前
小说在线阅读网站和小说管理系统 · 功能全解析
java·后端·python·springboot·ruoyi
源码宝4 小时前
基于 SpringBoot + Vue 的医院随访系统:技术架构与功能实现
java·vue.js·spring boot·架构·源码·随访系统·随访管理
昇腾CANN5 小时前
TileLang-Ascend 算子性能优化方法与实操
开发语言·javascript·性能优化·昇腾·cann
AGV算法笔记5 小时前
CVPR 2025 最新感知算法解读:GaussianLSS 如何用 Gaussian Splatting 重构 BEV 表示?
算法·重构·自动驾驶·3d视觉·感知算法·多视角视觉
沐知全栈开发5 小时前
ionic 手势事件详解
开发语言
lsx2024065 小时前
Bootstrap 按钮
开发语言
qinqinzhang5 小时前
Java 中的 IoC、AOP、MVC
java
神仙别闹5 小时前
基于 Python 实现 BERT 的情感分析模型
开发语言·python·bert