【算法沉淀】刷題筆記:并查集 帶權并查集+實戰講解

?🎉🎉歡迎光臨🎉🎉

🏅我是蘇澤,一位對技術充滿熱情的探索者和分享者。🚀🚀

🌟特別推薦給大家我的最新專欄《數據結構與算法:初學者入門指南》📘📘

希望能和大家一起學習!共同進步!

這是蘇澤的個人主頁可以看到我其他的內容哦👇👇

努力的蘇澤icon-default.png?t=N7T8http://suzee.blog.csdn.net

當談論并查集時,我們可以繼續使用上述的動物園比喻來解釋它的概念。

我們可以把并查集看作是一個動物園管理系統,幫助你管理動物們的歸屬關系。

在這個動物園中,每個動物都有一個獨特的編號,代表一個獨立的元素。一開始,每個動物都是獨立的,沒有與其他動物建立關系。

  1. 初始化(Init()函數)就像是給每個動物分配一個編號和一個獨立的籠子。這樣,它們就有了一個起始的歸屬地。

  2. 查找函數(Find()函數)就像是動物們在尋找自己所屬的籠子。當你給一個動物的編號,它會告訴你它所在的籠子。這樣,你可以快速找到任何動物所屬的籠子。

  3. 合并集合函數(Join()函數)就像是把兩個籠子合并在一起,讓兩個動物的集合變成一個更大的集合。當你把兩個動物放在同一個籠子里,它們就成為了同一個集合,共享同一個歸屬地。

class UnionFind {private int[] parent;public UnionFind(int size) {parent = new int[size];for (int i = 0; i < size; i++) {parent[i] = i; // 每個動物初始時獨立成為一個集合,自己是自己的根節點}}public int find(int x) {if (parent[x] != x) {parent[x] = find(parent[x]); // 使用路徑壓縮優化,將當前動物的父節點直接指向根節點}return parent[x]; // 返回動物所屬的籠子(根節點)}public void join(int x, int y) {int rootX = find(x);int rootY = find(y);if (rootX != rootY) {parent[rootX] = rootY; // 將兩個籠子合并,讓一個根節點指向另一個根節點}}
}

歷屆試題 國王的煩惱
問題描述
C 國由 n nn 個小島組成,為了方便小島之間聯絡,C 國在小島間建立了 m mm 座大橋,每座大橋連接兩座小島。兩個小島間可能存在多座橋連接。然而,由于海水沖刷,有一些大橋面臨著不能使用的危險。

如果兩個小島間的所有大橋都不能使用,則這兩座小島就不能直接到達了。然而,只要這兩座小島的居民能通過其他的橋或者其他的小島互相到達,他們就會安然無事。但是,如果前一天兩個小島之間還有方法可以到達,后一天卻不能到達了,居民們就會一起抗議。

現在 C 國的國王已經知道了每座橋能使用的天數,超過這個天數就不能使用了。現在他想知道居民們會有多少天進行抗議。

輸入格式
輸入的第一行包含兩個整數 n , m n, mn,m,分別表示小島的個數和橋的數量。
接下來 m mm 行,每行三個整數 a , b , t a, b, ta,b,t,分別表示該座橋連接 a aa 號和 b bb 號兩個小島,能使用t天。小島的編號從 1 開始遞增。

輸出格式
輸出一個整數,表示居民們會抗議的天數。

樣例輸入
4 4
1 2 2
1 3 2
2 3 1
3 4 3

樣例輸出
2
樣例說明
第一天后 2 和 3 之間的橋不能使用,不影響。
第二天后 1 和 2 之間,以及1和3之間的橋不能使用,居民們會抗議。
第三天后 3 和 4 之間的橋不能使用,居民們會抗議。

數據規模和約定
對于 30% 的數據,1 ≤ n ≤ 20 , 1 ≤ m ≤ 100 1\leq n \leq 20,1 \leq m \leq 1001≤n≤20,1≤m≤100;
對于 50% 的數據,1 ≤ n ≤ 500 , 1 ≤ m ≤ 10000 1 \leq n \leq 500,1 \leq m \leq 100001≤n≤500,1≤m≤10000;
對于 100% 的數據,1 ≤ n ≤ 10000 , 1 ≤ m ≤ 100000 , 1 ≤ a , b ≤ n , 1 ≤ t ≤ 100000 1 \leq n \leq 10000,1 \leq m \leq 100000,1\leq a, b \leq n, 1 \leq t \leq 1000001≤n≤10000,1≤m≤100000,1≤a,b≤n,1≤t≤100000。
?

首先,我們需要根據輸入的橋的信息構建并查集。

對于每座橋,如果它的使用天數超過了指定的天數,我們將這兩個小島合并成同一個集合。如果它的使用天數沒有超過指定的天數,說明這座橋可以使用,我們不需要對這兩個小島進行合并。

接下來,我們遍歷所有的橋,對于每座橋,我們查找連接的兩個小島是否屬于同一個集合。如果不屬于同一個集合,說明這兩個小島之間沒有其他路徑可以到達,居民們會抗議的天數加一。

最后,輸出居民們會抗議的天數即可。

import java.util.*;class UnionFind {private int[] parent;public UnionFind(int size) {parent = new int[size + 1];for (int i = 1; i <= size; i++) {parent[i] = i;}}public int find(int x) {if (parent[x] != x) {parent[x] = find(parent[x]);}return parent[x];}public void union(int x, int y) {int rootX = find(x);int rootY = find(y);if (rootX != rootY) {parent[rootX] = rootY;}}
}public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt();int m = scanner.nextInt();UnionFind uf = new UnionFind(n);for (int i = 0; i < m; i++) {int a = scanner.nextInt();int b = scanner.nextInt();int t = scanner.nextInt();if (t <= 2) {uf.union(a, b);}}int protestDays = 0;for (int i = 1; i <= n; i++) {if (uf.find(i) == i) {protestDays++;}}System.out.println(protestDays - 1);}
}

第二道題

問題描述
? ? ? ? 小藍國是一個水上王國, 有 2021 個城邦, 依次編號 1 到 2021。在任意兩 個城邦之間, 都有一座橋直接連接。

? ? ? ? 為了慶祝小藍國的傳統節日, 小藍國政府準備將一部分橋裝飾起來。

? ? ? ? 對于編號為 a 和 b 的兩個城邦, 它們之間的橋如果要裝飾起來, 需要的費 用如下計算:

? ? ? ? 找到 a 和 b 在十進制下所有不同的數位, 將數位上的數字求和。

? ? ? ? 例如, 編號為 2021 和 922 兩個城邦之間, 千位、百位和個位都不同, 將這些數位上的數字加起來是 (2+0+1)+(0+9+2)=14 。注意 922 沒有千位, 千位看成 0 。

? ? ? ? 為了節約開支, 小藍國政府準備只裝飾 2020 座橋, 并且要保證從任意一個 城邦到任意另一個城邦之間可以完全只通過裝飾的橋到達。

? ? ? ? 請問, 小藍國政府至少要花多少費用才能完成裝飾。

? ? ? ? 提示: 建議使用計算機編程解決問題。

答案提交
? ? ? ? 這是一道結果填空的題,你只需要算出結果后提交即可。本題的結果為一 個整數, 在提交答案時只填寫這個整數, 填寫多余的內容將無法得分。

這道題有兩個思路:

1.動態規劃

思路講解

首先,我們定義一個二維數組dp,其中dp[i][j]表示城邦i到城邦j之間需要裝飾的費用。

然后,我們可以使用動態規劃的思路來計算dp數組的值。對于每對城邦(i, j),我們可以通過考慮最后一段路徑(i, k, j)來計算dp[i][j]的值,其中k是城邦j的前一個城邦。

具體地,我們可以遍歷城邦k的所有可能取值(從1到2021),然后計算dp[i][j]的值。我們可以將dp[i][j]初始化為dp[i][k] + dp[k][j],然后再添加城邦kj之間的裝飾費用cost(k, j)。其中cost(k, j)可以通過將城邦kj的編號轉換為字符串,然后遍歷字符串中的每個字符,將字符轉換為數字并求和得到。

最后,我們需要計算小藍國政府至少要花費的費用,即dp[1][2021]

public class Main {public static int calculateCost(int x, int y) {String strX = String.valueOf(x);String strY = String.valueOf(y);int cost = 0;for (char digit : strX.toCharArray()) {if (strY.contains(String.valueOf(digit))) {cost += Character.getNumericValue(digit);}}return cost;}public static void main(String[] args) {int[][] dp = new int[2022][2022];for (int i = 1; i <= 2021; i++) {for (int j = 1; j <= 2021; j++) {if (i != j) {dp[i][j] = calculateCost(i, j);}}}for (int k = 1; k <= 2021; k++) {for (int i = 1; i <= 2021; i++) {for (int j = 1; j <= 2021; j++) {if (i != j && i != k && j != k) {dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[k][j]);}}}}int answer = dp[1][2021];System.out.println(answer);}
}

2.并查集

題目將城堡看作連通帶權無向圖,其中城堡的編號表示圖的節點,城堡之間的橋梁裝飾費用表示圖的邊權。

首先,我們定義一個并查集數據結構,用于合并城堡所屬的連通分量。

然后,我們遍歷所有的橋梁,計算每座橋梁的裝飾費用,并將費用作為邊權存儲在一個二維數組dp中。

接下來,我們使用并查集的思想,將連接費用為0的城堡合并到同一個連通分量中。

最后,我們計算所有城堡到第一個城堡的裝飾費用,即累加每個連通分量中的最小邊權。

這樣,我們就可以得到小藍國政府至少要花費的費用。

import java.util.Arrays;public class Main {public static class UnionFind {private int[] parent;private int[] rank;public UnionFind(int n) {parent = new int[n];rank = new int[n];Arrays.fill(rank, 1);for (int i = 0; i < n; i++) {parent[i] = i;}}public int find(int x) {if (parent[x] != x) {parent[x] = find(parent[x]);}return parent[x];}public void union(int x, int y) {int rootX = find(x);int rootY = find(y);if (rootX != rootY) {if (rank[rootX] > rank[rootY]) {parent[rootY] = rootX;} else if (rank[rootX] < rank[rootY]) {parent[rootX] = rootY;} else {parent[rootY] = rootX;rank[rootX]++;}}}}public static int calculateCost(int x, int y) {String strX = String.valueOf(x);String strY = String.valueOf(y);int cost = 0;for (char digit : strX.toCharArray()) {if (strY.contains(String.valueOf(digit))) {cost += Character.getNumericValue(digit);}}return cost;}public static void main(String[] args) {int n = 2021;UnionFind uf = new UnionFind(n + 1);int[][] dp = new int[n + 1][n + 1];// 構建并查集for (int i = 1; i <= n; i++) {for (int j = i + 1; j <= n; j++) {int cost = calculateCost(i, j);dp[i][j] = cost;dp[j][i] = cost;if (cost == 0) {uf.union(i, j);}}}// 合并連通分量int[] set = new int[n + 1];Arrays.fill(set, -1);for (int i = 1; i <= n; i++) {int root = uf.find(i);if (set[root] == -1) {set[root] = i;}}// 計算最小裝飾費用int answer = 0;for (int i = 1; i <= n; i++) {if (set[i] != -1) {answer += dp[1][set[i]];}}System.out.println(answer);}
}

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

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

相關文章

Day13:信息打點-JS架構框架識別泄漏提取API接口枚舉FUZZ爬蟲插件項目

目錄 JS前端架構-識別&分析 JS前端架構-開發框架分析 前端架構-半自動Burp分析 前端架構-自動化項目分析 思維導圖 章節知識點 Web&#xff1a;語言/CMS/中間件/數據庫/系統/WAF等 系統&#xff1a;操作系統/端口服務/網絡環境/防火墻等 應用&#xff1a;APP對象/API接…

QML學習之Text

文本顯示是界面開發中的重要內容&#xff0c;在Qt Quick模塊中提供了 Text 項來進行文本的顯示&#xff0c;其中可以使用 font 屬性組對文本字體進行設置&#xff1a; font.bold&#xff1a;是否加粗&#xff0c;取值為true或false font.capitalization&#xff1a;大寫策略&a…

01.20 校招 實習 內推 面經

綠*泡*泡VX&#xff1a; neituijunsir 交流*裙 &#xff0c;內推/實習/校招匯總表格 1、校招 | 中興微電子2024屆校園招聘 校招 | 中興微電子2024屆校園招聘 2、長城汽車2024大學生開放日上大分&#xff01; 長城汽車2024大學生開放日上大分&#xff01; 3、校招 | 江淮汽…

java程序員的金三銀四求職寶典(二)

程序員的金三銀四求職寶典 隨著春天的腳步漸近&#xff0c;對于許多程序員來說&#xff0c;一年中最繁忙、最重要的面試季節也隨之而來。金三銀四&#xff0c;即三月和四月&#xff0c;被廣大程序員視為求職的黃金時期。在這兩個月里&#xff0c;各大公司紛紛開放招聘&#xf…

倒計時36天

C-小紅關雞_牛客周賽 Round 35 (nowcoder.com) //超時 134.17/175 主要是循環這部分的問題 #include <bits/stdc.h> using namespace std; #define int long long const int N 2e5 6; const int inf 0x3f3f3f3f; int a[N]; void solve() {int n,k;cin>>n>…

多模態大語言模型的ai反饋增強機器人操作研究

本研究關注于利用大語言模型&#xff08;LLMs&#xff09;提供的自動化偏好反饋來增強決策過程 ○ 提出了一種多模態LLM&#xff0c;稱為CriticGPT&#xff0c;可以理解機器人操作任務中的軌跡視頻&#xff0c;并提供分析和偏好反饋 ○ 從獎勵建模的角度驗證了CriticGPT生成的…

使用 MongoDB Atlas 無服務器實例更高效地開發應用程序

使用 MongoDB Atlas無服務器實例更高效地開發應用程序 身為開發者&#xff0c;數據庫并不一定需要您來操心。您可不想耗費時間來預配置集群或調整集群大小。同樣地&#xff0c;您也不想操心因未能正確擴展而導致經費超標。 MongoDB Atlas 可為您提供多個數據庫部署選項。雖然…

【javascript】快速入門javascript

本文前言及說明 適合學過一門語言有一定基礎的人看。 省略最初學習編程時的各種編程重復的基礎知識。 javascript簡介 編程語言&#xff08;主前端&#xff09; 用途&#xff1a;主web前后端&#xff0c;游戲&#xff0c;干別人網站 優點&#xff1a;速度快&#xff0c;瀏…

一文掃盲:室內導航系統的應用場景和技術實現(入門級)

hello&#xff0c;我是貝格前端工場&#xff0c;之間搞過一些室內導航項目&#xff0c;有2D也有3D的&#xff0c;算是有些經驗&#xff0c;這里給大家分享一下室內導航的基本嘗試&#xff0c;歡迎老鐵們點贊、關注&#xff0c;如有需求可以私信我們。 一、室內導航是什么 室內…

Vue開發實例(十)Tabs標簽頁打開、關閉與路由之間的關系

創建標簽頁 一、創建標簽頁二、點擊菜單展示新標簽頁1、將標簽數據作為全局使用2、菜單點擊增加標簽頁3、處理重復標簽4、關閉標簽頁 三、點擊標簽頁操作問題1&#xff1a;點擊標簽頁選中菜單進行高亮展示問題2&#xff1a;點擊標簽頁路由也要跳轉 四、解決bug 先展示最終效果 …

Android 基礎入門 基礎簡介

1. 觀察App運行日志 2.Android 開發設計的編程語言 koltin Java c c 3.工程目錄結構 4.Gradle 5.build.gradle 文件解析 plugins {id("com.android.application")//用了哪些插件 主配置文件版本控制 所以這里不用寫版本 }android {namespace "com.tiger.myap…

【C++】每周一題——2024.3.3(手滑再寫一篇)

題目 Cpp 【問題描述】 輸入一個由若干個以空格分隔的單詞組成的英文文章&#xff0c;求文章中最短的單詞&#xff08;文章以英文句點”.”結束&#xff0c;且字符數不超過200&#xff09;. 【輸入格式】 一行&#xff0c;表示輸入的英文文章。 【輸出格式】 一行&#xff0c;表…

反向代理與負載均衡

目錄 反向代理 負載均衡 反向代理 代理角色&#xff1a; 正常情況下&#xff0c;客戶端&#xff08;如瀏覽器&#xff09;直接與服務器通信&#xff0c;但在反向代理中&#xff0c;Nginx充當客戶端和服務器之間的中介。客戶端向Nginx發送請求&#xff0c;而Nginx負責將請求轉…

基于springboot+vue的二手車交易系統

博主主頁&#xff1a;貓頭鷹源碼 博主簡介&#xff1a;Java領域優質創作者、CSDN博客專家、阿里云專家博主、公司架構師、全網粉絲5萬、專注Java技術領域和畢業設計項目實戰&#xff0c;歡迎高校老師\講師\同行交流合作 ?主要內容&#xff1a;畢業設計(Javaweb項目|小程序|Pyt…

金三銀四,風控建模面試全攻略:從簡歷準備到面試技巧

隨著春天的到來,招聘市場的 “金三銀四” 也悄然而至。公眾號的小伙伴問我有沒有面試相關指導課程,上完課后,把整理的部分材料通過文章分享給更多有需要的朋友。預祝大家順利獲得心儀的職位。本文將從簡歷準備、面試注意事項以及高頻面試問題三個方面,為你提供一份全面的風…

字符串判空錯誤

字符串判空錯誤 前端傳來的請求數據&#xff0c;若用只用String為null判斷&#xff0c;則忽略了str“”的情況&#xff0c;此時str不空&#xff0c;但str.length()0 RequestMapping(path "/add", method RequestMethod.POST)ResponseBodypublic String addDiscuss…

C++進階(二) 多態

一、多態的概念 多態的概念&#xff1a;通俗來說&#xff0c;就是多種形態&#xff0c; 具體點就是去完成某個行為&#xff0c;當不同的對象去完成時會 產生出不同的狀態。舉個栗子&#xff1a;比如買票這個行為&#xff0c;當普通人買票時&#xff0c;是全價買票&#xff1b;學…

Linux 查詢端口被占用命令

Linux 查詢端口被占用命令 1、lsof -i:端口號 用于查看某一端口的占用情況&#xff0c;比如查看8000端口使用情況&#xff0c;lsof -i:8000 lsof -i:8080&#xff1a;查看8080端口占用 lsof abc.txt&#xff1a;顯示開啟文件abc.txt的進程 lsof -c abc&#xff1a;顯示abc進…

Java中的List

List集合的特有方法 方法介紹 方法名描述void add(int index,E element)在此集合中的指定位置插入指定的元素E remove(int index)刪除指定索引處的元素&#xff0c;返回被刪除的元素E set(int index,E element)修改指定索引處的元素&#xff0c;返回被修改的元素E get(int inde…

動態規劃5,粉刷房子,買賣股票的最佳時期

粉刷房子 思路&#xff1a; 1.經驗題目要求 dp[i][0] 表示&#xff1a;粉刷到 i 位置的時候&#xff0c;最后一個位置粉刷上紅色&#xff0c;此時的最小花費。 dp[i][1] 表示&#xff1a;粉刷到 i 位置的時候&#xff0c;最后一個位置粉刷上藍色&#xff0c;此時的最小花費。…