LeetCode - 1319. 连通网络的操作次数

2024-05-11 17:38

本文主要是介绍LeetCode - 1319. 连通网络的操作次数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

描述

用以太网线缆将 n 台计算机连接成一个网络,计算机的编号从 0 到 n-1。线缆用 connections 表示,其中 connections[i] = [a, b] 连接了计算机 a 和 b。

网络中的任何一台计算机都可以通过网络直接或者间接访问同一个网络中其他任意一台计算机。

给你这个计算机网络的初始布线 connections,你可以拔开任意两台直连计算机之间的线缆,并用它连接一对未直连的计算机。请你计算并返回使所有计算机都连通所需的最少操作次数。如果不可能,则返回 -1 。 

 

示例 1:

输入:n = 4, connections = [[0,1],[0,2],[1,2]]
输出:1
解释:拔下计算机 1 和 2 之间的线缆,并将它插到计算机 1 和 3 上。
示例 2:

输入:n = 6, connections = [[0,1],[0,2],[0,3],[1,2],[1,3]]
输出:2
示例 3:

输入:n = 6, connections = [[0,1],[0,2],[0,3],[1,2]]
输出:-1
解释:线缆数量不足。
示例 4:

输入:n = 5, connections = [[0,1],[0,2],[3,4],[2,3]]
输出:0
 

提示:

1 <= n <= 10^5
1 <= connections.length <= min(n*(n-1)/2, 10^5)
connections[i].length == 2
0 <= connections[i][0], connections[i][1] < n
connections[i][0] != connections[i][1]
没有重复的连接。
两台计算机不会通过多条线缆连接。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/number-of-operations-to-make-network-connected/
 

求解

   class Solution {public:// 方法一,图深度优先搜索获取连通分量int makeConnected_1e(int n, vector<vector<int>> &connections) {if (connections.size() < n - 1) {// n个节点的图最小生成树是n-1条边,如果边少于n-1,肯定无法进行全部节点的连通return -1;}// 构造图,采用邻接表存储vector<vector<int>> graph(n, vector<int>());for (const auto &edge : connections) {graph[edge[0]].emplace_back(edge[1]);graph[edge[1]].emplace_back(edge[0]);}// 深度优先遍历visited.assign(n, false);int count = 0; // 连通分量for (int i = 0; i < n; ++i) {if (!visited[i]) {++count;dfs(graph, i);}}return count - 1;}// 方法二,图广度优先搜索获取连通分量int makeConnected_2e(int n, vector<vector<int>> &connections) {if (connections.size() < n - 1) {// n个节点的图最小生成树是n-1条边,如果边少于n-1,肯定无法进行全部节点的连通return -1;}// 构造图,采用邻接表存储vector<vector<int>> graph(n, vector<int>());for (const auto &edge : connections) {graph[edge[0]].emplace_back(edge[1]);graph[edge[1]].emplace_back(edge[0]);}// 广度优先遍历visited.assign(n, false);int count = 0; // 连通分量queue<int> q;for (int i = 0; i < n; ++i) {if (!visited[i]) {++count;q.emplace(i);visited[i] = true;  // 将顶点加入队列后,需要立马将其标志位置位已访问状态,因为后序肯定会访问到该顶点,避免多次加入相同顶点while (!q.empty()) {int v = q.front();q.pop();for (const auto &w : graph[v]) {if (!visited[w]) {q.emplace(w);visited[w] = true; // 将顶点加入队列后,需要立马将其标志位置位已访问状态}}}}}return count - 1;}// 方法三,并查集,速度最快,使用内存最少int makeConnected(int n, vector<vector<int>> &connections) {if (connections.size() < n - 1) {// n个节点的图最小生成树是n-1条边,如果边少于n-1,肯定无法进行全部节点的连通return -1;}// 并查集数据初始化rank.assign(n, 0);parent.assign(n, 0);for (int i = 0; i < n; ++i) {parent[i] = i;}// 根据边进行顶点关联for (const auto &edge : connections) {unionElements(edge[0], edge[1]);}return getConCount() - 1;}private:vector<bool> visited; // 图节点的访问标志vector<int> parent;  // 并查集数据结构vector<int> rank; // 并查集层级记录,用于优化// 并查集查找函数int find(int p) {while (p != parent[p]) {parent[p] = parent[parent[p]];p = parent[p];}return p;}// 并查集关联函数void unionElements(int p, int q) {int pid = find(p);int qid = find(q);if (pid != qid) {if (rank[pid] < rank[qid]) {parent[pid] = qid;return;}if (rank[pid] > rank[qid]) {parent[qid] = pid;return;}// rank[pid] == rank[qid]parent[pid] = parent[qid];++rank[qid];}}// 并查集计算连通分量函数int getConCount() {int count = 0;for (int i = 0; i < parent.size(); ++i) {if (i == parent[i]) {++count;}}return count;}// 图的深度优先搜索void dfs(const vector<vector<int>> &graph, int v) {visited[v] = true;for (auto w : graph[v]) {if (!visited[w]) {dfs(graph, w);}}}};

 

这篇关于LeetCode - 1319. 连通网络的操作次数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/980209

相关文章

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

ASIO网络调试助手之一:简介

多年前,写过几篇《Boost.Asio C++网络编程》的学习文章,一直没机会实践。最近项目中用到了Asio,于是抽空写了个网络调试助手。 开发环境: Win10 Qt5.12.6 + Asio(standalone) + spdlog 支持协议: UDP + TCP Client + TCP Server 独立的Asio(http://www.think-async.com)只包含了头文件,不依

poj 3181 网络流,建图。

题意: 农夫约翰为他的牛准备了F种食物和D种饮料。 每头牛都有各自喜欢的食物和饮料,而每种食物和饮料都只能分配给一头牛。 问最多能有多少头牛可以同时得到喜欢的食物和饮料。 解析: 由于要同时得到喜欢的食物和饮料,所以网络流建图的时候要把牛拆点了。 如下建图: s -> 食物 -> 牛1 -> 牛2 -> 饮料 -> t 所以分配一下点: s  =  0, 牛1= 1~

poj 3068 有流量限制的最小费用网络流

题意: m条有向边连接了n个仓库,每条边都有一定费用。 将两种危险品从0运到n-1,除了起点和终点外,危险品不能放在一起,也不能走相同的路径。 求最小的费用是多少。 解析: 抽象出一个源点s一个汇点t,源点与0相连,费用为0,容量为2。 汇点与n - 1相连,费用为0,容量为2。 每条边之间也相连,费用为每条边的费用,容量为1。 建图完毕之后,求一条流量为2的最小费用流就行了

poj 2112 网络流+二分

题意: k台挤奶机,c头牛,每台挤奶机可以挤m头牛。 现在给出每只牛到挤奶机的距离矩阵,求最小化牛的最大路程。 解析: 最大值最小化,最小值最大化,用二分来做。 先求出两点之间的最短距离。 然后二分匹配牛到挤奶机的最大路程,匹配中的判断是在这个最大路程下,是否牛的数量达到c只。 如何求牛的数量呢,用网络流来做。 从源点到牛引一条容量为1的边,然后挤奶机到汇点引一条容量为m的边

hdu 3065 AC自动机 匹配串编号以及出现次数

题意: 仍旧是天朝语题。 Input 第一行,一个整数N(1<=N<=1000),表示病毒特征码的个数。 接下来N行,每行表示一个病毒特征码,特征码字符串长度在1—50之间,并且只包含“英文大写字符”。任意两个病毒特征码,不会完全相同。 在这之后一行,表示“万恶之源”网站源码,源码字符串长度在2000000之内。字符串中字符都是ASCII码可见字符(不包括回车)。

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &