LC-2316. 统计无向图中无法互相到达点对数(DFS、并查集)

news/2024/7/20 23:03:37 标签: 深度优先, 算法

2316. 统计无向图中无法互相到达点对数

中等

给你一个整数 n ,表示一张 无向图 中有 n 个节点,编号为 0n - 1 。同时给你一个二维整数数组 edges ,其中 edges[i] = [ai, bi] 表示节点 aibi 之间有一条 无向 边。

请你返回 无法互相到达 的不同 点对数目

示例 1:

在这里插入图片描述

输入:n = 3, edges = [[0,1],[0,2],[1,2]]
输出:0
解释:所有点都能互相到达,意味着没有点对无法互相到达,所以我们返回 0 。

示例 2:

img

输入:n = 7, edges = [[0,2],[0,5],[2,4],[1,6],[5,4]]
输出:14
解释:总共有 14 个点对互相无法到达:
[[0,1],[0,3],[0,6],[1,2],[1,3],[1,4],[1,5],[2,3],[2,6],[3,4],[3,5],[3,6],[4,6],[5,6]]
所以我们返回 14 。

提示:

  • 1 <= n <= 105
  • 0 <= edges.length <= 2 * 105
  • edges[i].length == 2
  • 0 <= ai, bi < n
  • ai != bi
  • 不会有重复边。

DFS

class Solution {
    // 统计联通分量 个数 和 大小
    // 然后递推,求出点对个数
    // 例如 4 1 2
    // 4 * 1 + 5 * 2
    public long countPairs(int n, int[][] edges) {
        List<Integer>[] g = new ArrayList[n];
        Arrays.setAll(g, e -> new ArrayList<>());
        for(int[] e : edges){
            int x = e[0], y = e[1];
            g[x].add(y);
            g[y].add(x);
        }
        boolean[] vis = new boolean[n];
        List<Integer> list = new ArrayList<>();
        for(int i = 0; i < n; i++){
            if(!vis[i]){
                int cnt = dfs(i, -1, g, vis);
                list.add(cnt);
            }
        }
        long res = 0l, sum = 0l;
        for(Integer e : list){
            res += e * sum;
            sum += e;
        }
        return res;
    }

    private int dfs(int x, int fa, List<Integer>[] g, boolean[] vis){
        int res = 1;
        vis[x] = true;
        for(int y : g[x]){
            if(y != fa && !vis[y])
                res += dfs(y, x, g, vis);
        }
        return res;
    }
}

并查集

统计连通块大小可以用并查集做

class Solution {
    // 统计联通分量 个数 和 大小
    public long countPairs(int n, int[][] edges) {
        UF uf = new UF(n);
        for(int[] e : edges){
            uf.union(Math.max(e[0], e[1]), Math.min(e[0], e[1]));
        }
        Map<Integer, Integer> map = new HashMap<>();
        for(int i = 0; i < n; i++){
            map.merge(uf.find(i), 1, Integer::sum);
        }
        long res = 0l, sum = 0l;
        for(int x : map.keySet()){
            res += (long)map.get(x) * sum;
            sum += map.get(x);
        }
        return res;
    }
}

/* ------------ 并查集模版 ------------ */
class UF {
    int[] parent; // par数组用来存储根节点,par[x]=y表示x的根节点为y
    int[] size; // size[i]表示以i为根的联通块大小
    int count; // count表示连通块个数,每次调用union时count-1
    
    public UF(int n) {
        this.count = n;
        parent = new int[n];
        size = new int[n];
        for (int i = 0; i < n; i++) {
            parent[i] = i;
            size[i] = 1;
        }
    }
    
    public void union(int x, int y) {
        int rootx = find(x);
        int rooty = find(y);
        if (rootx == rooty) return;
        else//不是同一个根,即不在同一个集合,就合并
            parent[rootx] = rooty;
            size[rooty] += size[rootx];
        count--;
    }
    
    public int find(int x) {
        // 路径压缩
        if (parent[x] != x) {
            parent[x] = find(parent[x]);
        }
        return parent[x];
    }
}


http://www.niftyadmin.cn/n/5108941.html

相关文章

HP OfficeJet Pro 8020 如何更换碳粉盒

环境&#xff1a; HP OfficeJet Pro 8020 问题描述&#xff1a; HP OfficeJet Pro 8020 如何更换碳粉盒 解决方案&#xff1a; 更换碳粉盒 更换所有墨水不足的碳粉盒或空碳粉盒。 1.打开前挡盖&#xff0c;然后提起碳粉盒检修门。 打开打印机门 2.等待笔架停止后再继续操作…

FreeRTOS入门教程(事件组概念和函数使用)

文章目录 前言一、事件组概念二、事件组和信号量&#xff0c;队列的区别三、事件组相关函数三、事件组应用示例1.等待多个事件2.任务同步 总结 前言 本篇文章将带大家学习什么是事件组以及如何使用事件组。 一、事件组概念 事件组通常是由一组位&#xff08;bits&#xff09…

操作系统知识点学习

Java学习系列知识点纯干货&#xff1a; 1.Java学习之Java基础部分知识点—>传送门 2.Java学习之Java多线程知识点—>传送门 3.Java学习之数据库知识点—>传送门 4.计算机网络知识点—>传送门 5.Java学习之数据结构知识点—>传送门 6.操作系统知识点学习—>传…

【文献阅读】【NC 2023】基于分子组装的可解释深度学习方法实现精准逆合成预测以及路径规划

paper&#xff1a;Retrosynthesis prediction with an interpretable deep-learning framework based on molecular assembly tasks | Nature Communications Retrosynthesis prediction with an interpretable deep-learning framework based on molecular assembly tasks

fleek 第一次节点测试

一、创建用户​ 创建用户​ 我们建议创建一个具有管理权限的 non-root 用户。它允许我们安装任何系统要求。 您可以通过运行以下命令创建新用户并添加到 sudo 组&#xff1a; adduser lgtn 使用以下命令切换到新用户&#xff1a; su lgtn 将目录更改为新用户的家&#xf…

lodash常用方法合集

安装lodash 建议安装lodash-es&#xff0c;lodash-es 是 lodash 的 es modules 版本 &#xff0c;是着具备 ES6 模块化的版本&#xff0c;体积小。按需引入。 示例 npm i lodash-es import { chunk,compact } from lodash-es; /**按需引入*/ 1.chunk 数组分组 chunk(arra…

1600*D. Maximum Sum on Even Positions(贪心)

Problem - 1373D - Codeforces 解析&#xff1a; 显然可以发现&#xff0c;翻转数量为奇数是不影响结果&#xff0c;所以需要反转偶数个连续数字。 考虑贪心&#xff0c;我们每次反转相邻的两个数字&#xff0c;并且累计贡献&#xff0c;如果贡献为0则清空继续累计&#xff0c;…

ZCU106+ADRV9371+CPRO33-30.72+6 dB 衰减

文章目录 一、ZYNQ 平台二、ADRV9371三、CPRO33-30.72四、衰减器 一、ZYNQ 平台 之后使用 Zynq UltraScale MPSoC ZCU106&#xff0c;XCZU7EV 器件配备四核 ARM Cortex™-A53 应用处理器、双核 Cortex-R5 实时处理器、Mali™-400 MP2 图形处理单元、支持 4KP60 的 H.264/H.265…