【刷题笔记】第二天

一道图论相关的题目

3108. 带权图里旅途的最小代价

结论:
做与运算,结果不会大于当前值,也就是说与运算只能导致结果不变或越来越小,所以要使得边的and值最小,就是把每一个联通块的所有边都and一遍。

方法1:dfs

深度优先遍历每一个节点,并计算该节点所在的联通块内所有边的与值
两个点的联通情况,分三种可能:
1、两个点不在同一个联通块
2、两个点在一个联通块
3、两个点相同

class Solution {
    // 从u节点出发,计算联通块id里的边and值
    // u输入联通块id
    public int dfs(int u, int id, List<int[]>[] g, int[] ids) {
        ids[u] = id;
        int ans = -1; // -1的二进制数所有位全为1, -1 & x = x
        for (int[] cur : g[u]) {
            int v = cur[0];
            int w = cur[1]; 
            ans = ans & w; // 注意这句不能写在下面if里,如果写在if里,则不能保证所有的边都被and (因为两个节点的边可能不止一条),见解释1
            if (ids[v] == -1) {
                // 从u能走到v,说明v也属于联通块id
                ans = ans & dfs(v, id, g, ids);
            }
        }
        return ans;
    }
    public int[] minimumCost(int n, int[][] edges, int[][] query) {
        List<int[]>[] g = new ArrayList[n]; // g[x]:表示从x节点出边的<入点,边>集合
        for (int i = 0; i < n; ++i) {
            g[i] = new ArrayList<>();
        }
        for (int[] e : edges) {
            int u = e[0];
            int v = e[1];
            int w = e[2];
            g[u].add(new int[]{v, w});
            g[v].add(new int[]{u, w});
        }

        int[] ids = new int[n]; // 计算每一个节点(0 ~ n-1)所在的联通块编号
        Arrays.fill(ids, -1);
        ArrayList<Integer> andAns = new ArrayList<>(); // 每一个联通块的边的and值
        for (int i = 0; i < n; ++i) {
            // 计算所有点的联通块编号
            if (ids[i] == -1) {
                // i节点未计算过
                andAns.add(dfs(i, andAns.size(), g, ids));
            }
        }
        int[] res = new int[query.length];
        int index = 0;
        for (int[] q : query) {
            int x = q[0];
            int y = q[1];
            /**
            分三种情况:
            1. x和y不属于同一个联通快,返回-1
            2. x和y属于同一个联通块,返回联通块的and值
            3. x和y相同,返回0
             */
            if (ids[x] != ids[y]) {
                res[index++] = -1;
            }
            else if (ids[x] == ids[y]) {
                res[index++] = andAns.get(ids[x]);
            } else if (x == y) {
                res[index++] = 0;
            }
            
        }
        return res;
    }
}

解释1:如果把ans = ans & w;写在if里,就会忽略1这条边或者2这条边。因为假设and了1这条边,ids[1]就不为-1了,当遍历2这条边的时候,不会执行if里的语句。

image-20240411104034266

补充:

Arrays.fill(数组名, 填充值);
例如:
int[] ids = new int[n];
Arrays.fill(ids, -1);

方法2:并查集

遍历每一条边,如果边的两个节点不在一个集合,就合并,并计算新集合的and值

class Solution {
    public int find(int x, int[] p) {
        if (x != p[x]) {
            p[x] = find(p[x], p);
        }
        return p[x];
    }
    public int[] minimumCost(int n, int[][] edges, int[][] query) {
        int[] p = new int[n];
        for (int i = 0; i < n; ++i) {
            p[i] = i;
        }
        int[] and = new int[n]; // 代表节点的and值
        Arrays.fill(and, -1);
        for (int[] e : edges) {
            int u = e[0];
            int v = e[1];
            int w = e[2];
            int uFather = find(u, p);
            int vFather = find(v, p);
            
            and[vFather] &= w;
            if (uFather != vFather) {
                // u和v不在同一个集合就合并
                // u所在的集合合并到v所在的集合
                and[vFather] &= and[uFather]; // 只计算代表节点的and值
                p[uFather] = vFather;
            }
        }

        int[] res = new int[query.length];
        int index = 0;
        for (int[] q : query) {
            int u = q[0];
            int v = q[1];
            res[index++] =  u == v ? 0 : find(u, p) == find(v, p) ? and[find(u, p)] : -1;
        }
        return res;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/547082.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vue项目实战:基于用户身份的动态路由管理

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

201403-3 命令行选项

100分 #include <bits/stdc.h> using namespace std;int main() {string line;cin >> line;map<char, bool> dct; // true:带参数 false:不带参数for (int i 0; i < line.size(); i){if (line[i] ! :){dct.insert(pair<char, bool>(line[i], fals…

ubuntu 23.10.1 mysql 安装

注&#xff1a;请进入root用户模式下操作&#xff0c;若没有&#xff0c;输入命令前加上sudo 1、更新软件包列表 apt update2、安装最新版的Mysql服务器 apt install mysql-server -y如果不加-y 会在安装过程中&#xff0c;系统将提示你设置MySQL的root密码。确保密码足够强…

职场成长之路:如何规划与实现

在职场中&#xff0c;每个人都希望实现自己的职业目标和成长。然而&#xff0c;职场成长并非一蹴而就&#xff0c;需要有明确的规划和方法。本文将探讨如何在职场中规划与实现成长&#xff0c;帮助您迈向成功之路。 一、明确职业目标 1. 自我认知&#xff1a;了解自己的兴趣、…

C语言双向链表

1. 链表的分类 链表的种类很多&#xff0c;主要由三个要素决定&#xff1a;是否带头&#xff0c;单向还是双向&#xff0c;是否循环。 根据这三个要素的组合&#xff0c;共可得到8&#xff08;2*2*2&#xff09;种链表 而我们常用的链表有两种&#xff1a; 1. 单链表&#xf…

鸿蒙原生应用元服务-访问控制(权限)开发Stage模型向用户申请授权

一、向用户申请授权 当应用需要访问用户的隐私信息或使用系统能力时&#xff0c;例如获取位置信息、访问日历、使用相机拍摄照片或录制视频等&#xff0c;应该向用户请求授权。这需要使用 user_grant 类型权限。在此之前&#xff0c;应用需要进行权限校验&#xff0c;以判断当前…

02_按键控制LED

按键控制LED 按键控制LED 按键控制LED while (1){//按键控制LEDif(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_5)GPIO_PIN_RESET)//读取PC5引脚状态&#xff0c;即检测按键是否按下{while(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_5)GPIO_PIN_RESET);//松手检测HAL_GPIO_WritePin(GPIOA,GPIO_PI…

【JavaWeb】Day45.Mybatis——入门程序

什么是MyBatis? MyBatis是一款优秀的持久层框架&#xff0c;用于简化JDBC的开发。 &#xff08;持久层&#xff1a;指的是就是数据访问层(dao)&#xff0c;是用来操作数据库的。&#xff09; &#xff08;框架&#xff1a;是一个半成品软件&#xff0c;是一套可重用的、通用…

【软考】UML中的图之类图

目录 1. 说明2. 图示3. 类图使用方式3.1 对系统的词汇建模3.2 对简单的协作建模3.3 对逻辑数据库模式建模 1. 说明 1.类图&#xff08;Class Diagram&#xff09;展现了一组对象、接口、协作和它们之间的关系。2.在面向对象系统的建模中所建立的最常见的图是类图。3.类图给出系…

Openwrt21.02支持SKW78(MT7621)

1.获取SDK 1.下载Openwrt源码 下载链接&#xff1a; git clone --branch openwrt-21.02 https://gitee.com/cocos_yang/openwrt.git 下载完后&#xff0c;会有一个openwrt目录&#xff0c;进入openwrt目录 cd openwrt 修改feeds.conf.default的内容&#xff0c;如下所示&#x…

操作系统(1)计算机存储结构

文章目录 一、计算机存储结构1、基本概念2、计算机存储结构的组成部分3、局部性原理4、高速缓存4.1、基本概念4.2、工作原理4.3、层次结构4.4、对系统性能的影响4.5、一致性问题 5、寄存器5.1&#xff0c;种类5.2&#xff0c;特点5.3、作用5.4、寄存器与缓存的差异 前言 计算机…

MybatisPlus实现数据权限隔离

引言 Mybatis Plus对Mybatis做了无侵入的增强&#xff0c;非常的好用&#xff0c;今天就给大家介绍它的其中一个实用功能&#xff1a;数据权限插件。 数据权限插件的应用场景和多租户的动态拦截拼接SQL一样。建议点赞收藏关注&#xff0c;方便以后复习查阅。 依赖 首先导入M…

【网安小白成长之路】7.burp基本使用

&#x1f42e;博主syst1m 带你 acquire knowledge&#xff01; ✨博客首页——syst1m的博客&#x1f498; &#x1f51e; 《网安小白成长之路(我要变成大佬&#x1f60e;&#xff01;&#xff01;)》真实小白学习历程&#xff0c;手把手带你一起从入门到入狱&#x1f6ad; &…

计算机网络3——数据链路层1

文章目录 一、介绍1、基础2、内容 二、数据链路层的几个共同问题1、数据链路和帧2、三个基本问题1&#xff09;封装成帧2&#xff09;透明传输3&#xff09;差错检测 三、点对点协议 PPP1、PPP协议的特点1&#xff09;PPP 协议应满足的需求2&#xff09;PPP 协议的组成 2、PPP协…

vmware安装ubuntu-18.04系统

一、软件下载 百度网盘&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1fK2kygRdSux1Sr1sOKOtJQ 提取码&#xff1a;twsb 二、安装ubuntu系统 1、把ubuntu-18.04的压缩包下载下来&#xff0c;并且解压 2、打开vmware软件&#xff0c;点击文件-打开 3、选择我们刚刚解…

限制登录Linux服务器的几种方式

一.第一种方法 通过修改TCP Wrappers服务访问控制来实现限制登录Linux 1.这里以sshd服务为例&#xff0c;配置完成后&#xff0c;只允许配置允许的IP才能ssh连接本机服务器&#xff0c;其他IP拒绝判断某一个基于tcp协议的服务是否支持tcp_wrapper&#xff0c;要先判断它是否支…

【C语言】<动态内存管理>我的C语言终末章

&#xff1c;动态内存管理&#xff1e; 1. 为什么要有动态内存分配2. malloc和free2.1 malloc2.2 free 3. calloc和realloc3.1 calloc3.2 realloc 4.常见的动态内存错误4.1 对NULL指针的解引用操作4.2 对动态开辟空间的越界访问4.3 对非动态开辟内存使用free释放4.4 使用free释…

Linux下SPI设备驱动实验:实现SPI发送/接收数据的函数

一. 简介 前面文章介绍了SPI设备数据收发处理流程&#xff0c;后面几篇文章实现了SPI设备驱动框架&#xff0c;加入了字符设备驱动框架代码。文章如下&#xff1a; SPI 设备驱动编写流程&#xff1a;SPI 设备数据收发处理流程中涉及的结构体与函数-CSDN博客 SPI 设备驱动编写…

PgSQL之WITH Queries/Statement

PostgreSQL WITH 子句 在 PostgreSQL 中&#xff0c;WITH 子句提供了一种编写辅助语句的方法&#xff0c;以便在更大的查询中使用。 WITH 子句有助于将复杂的大型查询分解为更简单的表单&#xff0c;便于阅读。这些语句通常称为通用表表达式&#xff08;Common Table Express…

基于有序抖动块截断编码的水印嵌入和提取算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 噪声测试 旋转测试 压缩测试 2.算法运行软件版本 matlab2022a 3.部分核心程序 ............................................................…