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

    
}
相关推荐
AC赳赳老秦3 分钟前
OpenClaw+Power Apps 实战:自动生成 Power Apps 应用、连接 Excel 数据源
大数据·开发语言·python·serverless·excel·deepseek·openclaw
提笔了无痕5 分钟前
如何用Go实现整套RAG流程
开发语言·后端·golang
(Charon)7 分钟前
【C++ 面试高频基础:指针、引用、const、static、new/delete 总结】
java·开发语言
一只齐刘海的猫9 分钟前
【Leetcode】找到字符串中所有字母异位词
算法·leetcode·职场和发展
Yeats_Liao25 分钟前
Feed流系统设计(三):数据模型与存储设计,从表结构到Redis收件箱
java·javascript·redis
JiaHao汤30 分钟前
分布式事务方案全景:从理论到 Seata 落地
java·分布式·spring·spring cloud
海清河晏11131 分钟前
数据结构 | 八大排序
数据结构·算法·排序算法
2601_9618752442 分钟前
法考考试时间安排及科目|时间表|资料已整理
开发语言·c#·inverted-index·suffix-tree·sstable·r-tree·lsm-tree
AI科技星1 小时前
数术工坊第八卷:算力革命
c语言·开发语言·网络·量子计算·agi
geovindu1 小时前
go: Generators Pattern
开发语言·后端·设计模式·golang·生成器模式