代碼隨想錄算法訓練營第五十六天 | 108.冗余連接 109.冗余連接II

108. 冗余連接

卡碼網題目鏈接(ACM模式)(opens new window)

題目描述

有一個圖,它是一棵樹,他是擁有 n 個節點(節點編號1到n)和 n - 1 條邊的連通無環無向圖(其實就是一個線形圖),如圖:

現在在這棵樹上的基礎上,添加一條邊(依然是n個節點,但有n條邊),使這個圖變成了有環圖,如圖

先請你找出冗余邊,刪除后,使該圖可以重新變成一棵樹。

輸入描述

第一行包含一個整數 N,表示圖的節點個數和邊的個數。

后續 N 行,每行包含兩個整數 s 和 t,表示圖中 s 和 t 之間有一條邊。

輸出描述

輸出一條可以刪除的邊。如果有多個答案,請刪除標準輸入中最后出現的那條邊。

輸入示例

3
1 2
2 3
1 3

輸出示例

1 3

提示信息

圖中的 1 2,2 3,1 3 等三條邊在刪除后都能使原圖變為一棵合法的樹。但是 1 3 由于是標準輸入里最后出現的那條邊,所以輸出結果為 1 3

數據范圍:

1 <= N <= 1000.

我們就可以從前向后遍歷每一條邊(因為優先讓前面的邊連上),邊的兩個節點如果不在同一個集合,就加入集合(即:同一個根節點)。

如圖所示,節點A 和節點 B 不在同一個集合,那么就可以將兩個 節點連在一起。

如果邊的兩個節點已經出現在同一個集合里,說明著邊的兩個節點已經連在一起了,再加入這條邊一定就出現環了。

如圖所示:

已經判斷 節點A 和 節點B 在在同一個集合(同一個根),如果將 節點A 和 節點B 連在一起就一定會出現環。

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

卡碼網題目鏈接(ACM模式)(opens new window)

題目描述

有一種有向樹,該樹只有一個根節點,所有其他節點都是該根節點的后繼。該樹除了根節點之外的每一個節點都有且只有一個父節點,而根節點沒有父節點。有向樹擁有 n 個節點和 n - 1 條邊。如圖:

現在有一個有向圖,有向圖是在有向樹中的兩個沒有直接鏈接的節點中間添加一條有向邊。如圖:

輸入一個有向圖,該圖由一個有著 n 個節點(節點編號 從 1 到 n),n 條邊,請返回一條可以刪除的邊,使得刪除該條邊之后該有向圖可以被當作一顆有向樹。

輸入描述

第一行輸入一個整數 N,表示有向圖中節點和邊的個數。

后續 N 行,每行輸入兩個整數 s 和 t,代表這是 s 節點連接并指向 t 節點的單向邊

輸出描述

輸出一條可以刪除的邊,若有多條邊可以刪除,請輸出標準輸入中最后出現的一條邊。

輸入示例

3
1 2
1 3
2 3

輸出示例

2 3

提示信息

在刪除 2 3 后有向圖可以變為一棵合法的有向樹,所以輸出 2 3

數據范圍:

1 <= N <= 1000.

本題的本質是 :有一個有向圖,是由一顆有向樹 + 一條有向邊組成的 (所以此時這個圖就不能稱之為有向樹),現在讓我們找到那條邊 把這條邊刪了,讓這個圖恢復為有向樹。

還有“若有多條邊可以刪除,請輸出標準輸入中最后出現的一條邊”,這說明在兩條邊都可以刪除的情況下,要刪順序靠后的邊!

我們來想一下 有向樹的性質,如果是有向樹的話,只有根節點入度為0,其他節點入度都為1(因為該樹除了根節點之外的每一個節點都有且只有一個父節點,而根節點沒有父節點)。

所以情況一:如果我們找到入度為2的點,那么刪一條指向該節點的邊就行了。

如圖:

找到了節點3 的入度為2,刪 1 -> 3 或者 2 -> 3 。選擇刪順序靠后便可。

但 入度為2 還有一種情況,情況二,只能刪特定的一條邊,如圖:

節點3 的入度為 2,但在刪除邊的時候,只能刪 這條邊(節點1 -> 節點3),如果刪這條邊(節點4 -> 節點3),那么刪后本圖也不是有向樹了(因為找不到根節點)。

綜上,如果發現入度為2的節點,我們需要判斷 刪除哪一條邊,刪除后本圖能成為有向樹。如果是刪哪個都可以,優先刪順序靠后的邊。

情況三: 如果沒有入度為2的點,說明 圖中有環了(注意是有向環)。

如圖:

對于情況三,刪掉構成環的邊就可以了。

import java.util.*;/* * 冗余連接II。主要問題是存在入度為2或者成環,也可能兩個問題同時存在。* 1.判斷入度為2的邊 * 2.判斷是否成環(并查集)*/public class Main {/*** 并查集模板*/static class Disjoint {private final int[] father;public Disjoint(int n) {father = new int[n];for (int i = 0; i < n; i++) {father[i] = i;}}public void join(int n, int m) {n = find(n);m = find(m);if (n == m) return;father[n] = m;}public int find(int n) {return father[n] == n ? n : (father[n] = find(father[n]));}public boolean isSame(int n, int m) {return find(n) == find(m);}}static class Edge {int s;int t;public Edge(int s, int t) {this.s = s;this.t = t;}}static class Node {int id;int in;int out;}public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt();List<Edge> edges = new ArrayList<>();Node[] nodeMap = new Node[n + 1];for (int i = 1; i <= n; i++) {nodeMap[i] = new Node();}Integer doubleIn = null;for (int i = 0; i < n; i++) {int s = scanner.nextInt();int t = scanner.nextInt();//記錄入度nodeMap[t].in++;if (!(nodeMap[t].in < 2)) doubleIn = t;Edge edge = new Edge(s, t);edges.add(edge);}Edge result = null;//存在入度為2的節點,既要消除入度為2的問題同時解除可能存在的環if (doubleIn != null) {List<Edge> doubleInEdges = new ArrayList<>();for (Edge edge : edges) {if (edge.t == doubleIn) doubleInEdges.add(edge);if (doubleInEdges.size() == 2) break;}Edge edge = doubleInEdges.get(1);if (isTreeWithExclude(edges, edge, nodeMap)) {result = edge;} else {result = doubleInEdges.get(0);}} else {//不存在入度為2的節點,則只需要解除環即可result = getRemoveEdge(edges, nodeMap);}System.out.println(result.s + " " + result.t);}public static boolean isTreeWithExclude(List<Edge> edges, Edge exculdEdge, Node[] nodeMap) {Disjoint disjoint = new Disjoint(nodeMap.length + 1);for (Edge edge : edges) {if (edge == exculdEdge) continue;//成環則不是樹if (disjoint.isSame(edge.s, edge.t)) {return false;}disjoint.join(edge.s, edge.t);}return true;}public static Edge getRemoveEdge(List<Edge> edges, Node[] nodeMap) {int length = nodeMap.length;Disjoint disjoint = new Disjoint(length);for (Edge edge : edges) {if (disjoint.isSame(edge.s, edge.t)) return edge;disjoint.join(edge.s, edge.t);}return null;}}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/73364.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/73364.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/73364.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

什么是索引?為什么要使用B樹作為索引數據結構?

MySQL的事務特性 1.原子性:原子性就是這個事件要么執行完,要么沒執行,不會存在中間狀態,與C中華那個加鎖避免多線程競爭是一個道理; 2.一致性:保持事件的操作對象雙方某數據之和是不變的,就以轉賬為例,A轉給B100塊,那么A的余額多100,B的余額就必須少100; 3.隔離性:隔離就是獨…

pyqt5報錯:qt.qpa.plugin: Could not find the Qt platform plugin “xcb“(已解決)

我在使用pyqt庫的時候報錯&#xff1a; qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in \ "/mnt/private_disk/anaconda3/envs/aot-manip/lib/python3.8/site-packages/PyQt5/Qt5/plugins/platforms" even though it was found. This ap…

AI大模型全攻略:原理 · 部署 · Prompt · 場景應用

?? AI大模型全攻略:原理 部署 Prompt 場景應用 本文從基礎原理到實踐部署,再到 Prompt 工程與典型應用案例,全方位解析 AI 大模型的學習路徑與使用方法,適合開發者、產品經理、技術愛好者等不同背景讀者。 ?? 一、什么是 AI 大模型? AI 大模型(Large Language Mo…

2024年MathorCup數學建模D題量子計算在礦山設備配置及運營中的建模應用解題文檔與程序

2024年第十四屆MathorCup高校數學建模挑戰賽 D題 量子計算在礦山設備配置及運營中的建模應用 原題再現&#xff1a; 隨著智能技術的發展&#xff0c;智慧礦山的概念越來越受到重視。越來越多的設備供應商正在向智慧礦山整體解決方案供應商轉型&#xff0c;是否具備提供整體解…

Flink 流處理框架的核心特性

文章目錄 事件時間支持Flink狀態編程一、狀態的類型1. 托管狀態&#xff08;Managed State&#xff09;2. 原始狀態&#xff08;Raw State&#xff09; 二、狀態的管理和容錯 Flink端到端的一致性1、檢查點機制2、冪等3、事務 水位線窗口操作1、窗口類型2、窗口操作的時間語義 …

交換機(access端口)

任務&#xff1a;對access有更深入的理解 通過網盤分享的文件&#xff1a;交換機&#xff08;access&#xff09;.zip 鏈接: https://pan.baidu.com/s/1cMC6Na_1PLo6zOHazFplQQ?pwd23a5 提取碼: 23a5 SW1 <Huawei>sys [Huawei]dis vlan The total number of vlans …

《鳥哥的Linux私房菜基礎篇》---5 vim 程序編輯器

目錄 一、vim程序編輯器的簡介 二、命令模式快捷鍵&#xff08;默認模式&#xff09; 1、光標移動 2、編輯操作 3、搜索與替換 三、插入模式快捷鍵 四、底行模式快捷鍵&#xff08;按&#xff1a;進入&#xff09; 五、高級技巧 1、分屏操作 2、多文件編輯 3、可視化…

AI大白話(四):自然語言處理——AI是如何理解和生成人類語言的?

??引言: 專欄:《AI大白話》 AI大白話(一):5分鐘了解AI到底是什么? AI大白話(二):機器學習——AI是怎么“學習“的? AI大白話(三):深度學習——AI的‘大腦‘是如何構建的? 大家好!歡迎回到"AI大白話"系列。前面我們聊了AI的基本概念、機器學習的原理…

擴展卡爾曼濾波

1.非線性系統的線性化 標準卡爾曼濾波 適用于線性化系統&#xff0c;擴展卡爾曼濾波 則擴展到了非線性系統&#xff0c;核心原理就是將非線性系統線性化&#xff0c;主要用的的知識點是 泰勒展開&#xff08;我另外一篇文章的鏈接&#xff09;&#xff0c;如下是泰勒展開的公式…

安裝unsloth

我在llamafactory微調LLM&#xff0c;簡單測了一些&#xff08;很不精準&#xff09;&#xff0c;加速方法中unsloth比flash_attention速度快了40%&#xff0c;顯存占用減少15%&#xff1b; 創建虛擬環境&#xff1a;conda create -n env_name python3.10, 然后conda activate…

關于 51 單片機顯示多個數碼管時出現殘影

殘影現象&#xff1a; 出現殘影代碼&#xff1a; #include <REGX52.H> #include <INTRINS.H> void Delayxms(unsigned int x) //11.0592MHz {while(x){unsigned char i, j;_nop_();i 2;j 199; do{while (--j);} while (--i);x--;} } void DisplayDigitalNumb…

STM32學習筆記之常用外設接口(原理篇)

&#x1f4e2;&#xff1a;如果你也對機器人、人工智能感興趣&#xff0c;看來我們志同道合? &#x1f4e2;&#xff1a;不妨瀏覽一下我的博客主頁【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸對你有幫助&#xff0c;可點贊 &#x1f44d;…

InnoDB 引擎核心知識點

InnoDB 引擎核心知識點 6.1 邏輯存儲結構 表空間&#xff08;Tablespace&#xff09;&#xff1a;所有數據邏輯上存儲在一個表空間中&#xff0c;物理上可能由多個文件組成。段&#xff08;Segment&#xff09;&#xff1a;分為數據段&#xff08;B樹葉子節點&#xff09;、索引…

深度學習 Deep Learning 第9章 卷積網絡 CNN

深度學習 Deep Learning 第9章 卷積網絡 章節概述 本章深入探討了卷積網絡的原理、變體及其在深度學習中的應用。卷積網絡通過卷積操作實現了參數共享和稀疏連接&#xff0c;顯著提高了模型的效率和性能。本章首先介紹了卷積操作的基本形式及其在不同數據維度上的應用&#x…

基于MATLAB的渦旋光和高斯光疊加產生平頂光

強度疊加耦合成平頂光&#xff0c;不發生干涉 通過分別生成高斯光和渦旋光的強度分布&#xff0c;然后按合適的權重將它們疊加&#xff0c;得到近似平頂光&#xff08;flat‐top beam&#xff09;的效果。由于我們只是將強度相加&#xff08;而非復振幅疊加&#xff09;&#…

wordpress-網站百寶箱插件

含置頂,網頁寵物, 哀悼, 禁止復制, 禁止查看源碼, 彈幕, WP優化,媒體分類,預加載,定時發布,在線客服, 留言板, 手機客服, 網站背景, 公告, 跑馬燈, 水印, 分享, 打賞, 海報圖, 廣告,數據庫管理,圖片加載特效。等綜合功能插件

北斗導航 | 基于北斗三號短報文通信的北斗-YOLO融合系統原理,算法公式,系統流程框圖,matlab代碼,應用場景

以下是關于基于北斗三號短報文通信的北斗-YOLO融合系統的詳細解析,包含原理、算法公式、系統流程、Matlab代碼框架和應用場景。一、系統原理 北斗-YOLO融合系統結合了北斗三號短報文通信(雙向通信能力)和YOLO目標檢測算法,用于在無地面網絡覆蓋區域實現實時目標檢測與數據傳…

Vue 中的日期格式化實踐:從原生 Date 到可視化展示!!!

&#x1f4c5; Vue 中的日期格式化實踐&#xff1a;從原生 Date 到可視化展示 &#x1f680; 在數據可視化場景中&#xff0c;日期時間的格式化顯示是一個高頻需求。本文將以一個邀請碼關系樹組件為例&#xff0c;深入解析 Vue 中日期格式化的 核心方法、性能優化 和 最佳實踐…

試試智能體工作流,自動化搞定運維故障排查

APO 1.5.0版本全新推出的智能體工作流功能&#xff0c;讓運維經驗不再零散&#xff01;只需將日常的運維操作和故障排查經驗轉化為標準化流程&#xff0c;就能一鍵復用&#xff0c;效率翻倍&#xff0c;從此告別重復勞動&#xff0c;把時間留給更有價值的創新工作。更貼心的是&…

LeetCode-215. 數組中的第K個最大元素

1、題目描述 給定整數數組 nums 和整數 k&#xff0c;請返回數組中第 k 個最大的元素。 請注意&#xff0c;你需要找的是數組排序后的第 k 個最大的元素&#xff0c;而不是第 k 個不同的元素。 你必須設計并實現時間復雜度為 O(n) 的算法解決此問題。 示例 1: 輸入: [3,2,1…