圖論 - 最小生成樹(Prime、Kruskal)

文章目錄

  • 前言
  • Part 1:Prim算法求最小生成樹
    • 1.題目描述
        • 輸入格式
        • 輸出格式
        • 數據范圍
        • 輸入樣例
        • 輸出樣例
    • 2.算法
  • Part 2:Kruskal算法求最小生成樹
    • 1.題目描述
        • 輸入格式
        • 輸出格式
        • 數據范圍
        • 輸入樣例
        • 輸出樣例
    • 2.算法

前言

在這里插入圖片描述

本篇博客介紹兩種求最小生成樹的方法:即Prime算法和Kruskal算法。Prime算法用于稠密圖,也可以與Dijkstra類似用堆優化(詳見《圖論 - 最短路(Dijkstra、Bellman-Ford、SPFA、Floyd)》),用于稀疏圖,但是稀疏圖的時候求最小生成樹,Kruskal 算法更加實用,所以本篇博客將不介紹堆優化的Prime算法。即:稠密圖用樸素Prime算法,稀疏圖用Kruskal 算法即可。

Part 1:Prim算法求最小生成樹

1.題目描述

給定一個 n 個點 m 條邊的無向圖,圖中可能存在重邊和自環,邊權可能為負數。

求最小生成樹的樹邊權重之和,如果最小生成樹不存在則輸出 impossible

給定一張邊帶權的無向圖 G=(V,E),其中 V 表示圖中點的集合,E 表示圖中邊的集合,n=|V|,m=|E|。

由 V 中的全部 n 個頂點和 E 中 n?1 條邊構成的無向連通子圖被稱為 G 的一棵生成樹,其中邊的權值之和最小的生成樹被稱為無向圖 G 的最小生成樹。

輸入格式

第一行包含兩個整數 n 和 m。

接下來 m 行,每行包含三個整數 u,v,w,表示點 u 和點 v 之間存在一條權值為 w 的邊。

輸出格式

共一行,若存在最小生成樹,則輸出一個整數,表示最小生成樹的樹邊權重之和,如果最小生成樹不存在則輸出 impossible

數據范圍

1≤n≤500,
1≤m≤105,
圖中涉及邊的邊權的絕對值均不超過 10000。

輸入樣例
4 5
1 2 1
1 3 2
1 4 3
2 3 2
3 4 4
輸出樣例
6

2.算法

  • prim 算法采用的是一種貪心的策略
  • prim 算法做的事情是:給定一個無向圖,在圖中選擇若干條邊把圖的所有節點連起來。要求邊長之和最小。在圖論中,叫做求最小生成樹
  • 每次將離連通部分的最近的點和點對應的邊加入的連通部分,連通部分逐漸擴大,最后將整個圖連通起來,并且邊長之和最小
  • 與Dijkstra算法求最短路唯一的區別在于所求距離并非該點到源點的距離(詳見《圖論 - 最短路(Dijkstra、Bellman-Ford、SPFA、Floyd)》),而是該點到已選點集合的最短距離
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;const int N = 510;
int g[N][N];//存儲圖
int dt[N];//存儲各個節點到生成樹的距離
int st[N];//節點是否被加入到生成樹中
int pre[N];//節點的前去節點
int n, m;//n 個節點,m 條邊void prim()
{memset(dt,0x3f, sizeof(dt));//初始化距離數組為一個很大的數(10億左右)int res= 0;dt[1] = 0;//從 1 號節點開始生成 for(int i = 0; i < n; i++)//每次循環選出一個點加入到生成樹{int t = -1;for(int j = 1; j <= n; j++)//每個節點一次判斷{if(!st[j] && (t == -1 || dt[j] < dt[t]))//如果沒有在樹中,且到樹的距離最短,則選擇該點t = j;}//如果孤立點,直返輸出不能,然后退出if(dt[t] == 0x3f3f3f3f) {cout << "impossible";return;}st[t] = 1;// 選擇該點res += dt[t];for(int i = 1; i <= n; i++)//更新生成樹外的點到生成樹的距離{if(dt[i] > g[t][i] && !st[i])//從 t 到節點 i 的距離小于原來距離,則更新。{dt[i] = g[t][i];//更新距離pre[i] = t;//從 t 到 i 的距離更短,i 的前驅變為 t.}}}cout << res;}void getPath()//輸出各個邊
{for(int i = n; i > 1; i--)//n 個節點,所以有 n-1 條邊。{cout << i <<" " << pre[i] << " "<< endl;// i 是節點編號,pre[i] 是 i 節點的前驅節點。他們構成一條邊。}
}int main()
{memset(g, 0x3f, sizeof(g));//各個點之間的距離初始化成很大的數cin >> n >> m;//輸入節點數和邊數while(m --){int a, b, w;cin >> a >> b >> w;//輸出邊的兩個頂點和權重g[a][b] = g[b][a] = min(g[a][b],w);//存儲權重}prim();//求最下生成樹//getPath();//輸出路徑return 0;
}

Part 2:Kruskal算法求最小生成樹

1.題目描述

給定一個 n 個點 m 條邊的無向圖,圖中可能存在重邊和自環,邊權可能為負數。

求最小生成樹的樹邊權重之和,如果最小生成樹不存在則輸出 impossible

給定一張邊帶權的無向圖 G=(V,E),其中 V 表示圖中點的集合,E 表示圖中邊的集合,n=|V|,m=|E|。

由 V 中的全部 n 個頂點和 E 中 n?1 條邊構成的無向連通子圖被稱為 G 的一棵生成樹,其中邊的權值之和最小的生成樹被稱為無向圖 G 的最小生成樹。

輸入格式

第一行包含兩個整數 n 和 m。

接下來 m 行,每行包含三個整數 u,v,w,表示點 u 和點 v 之間存在一條權值為 w 的邊。

輸出格式

共一行,若存在最小生成樹,則輸出一個整數,表示最小生成樹的樹邊權重之和,如果最小生成樹不存在則輸出 impossible

數據范圍

1≤n≤105,
1≤m≤2?105,
圖中涉及邊的邊權的絕對值均不超過 1000。

輸入樣例
4 5
1 2 1
1 3 2
1 4 3
2 3 2
3 4 4
輸出樣例
6

2.算法

  • prim 算法采用的是一種貪心的策略
  • 將所有邊按照權值的大小進行升序排序,然后從小到大一一判斷
  • 如果這個邊與之前選擇的所有邊不會組成回路(用并查集判斷),就選擇這條邊分;反之,舍去
  • 直到具有 n 個頂點的連通網篩選出來 n-1 條邊為止
  • 篩選出來的邊和所有的頂點構成此連通網的最小生成樹
#include <iostream>
#include <cstring>
#include <algorithm>using namespace std;const int N = 100010;int p[N];//保存并查集struct E
{int a;int b;int w;//通過邊長進行排序bool operator < (const E& rhs){return this->w < rhs.w;}}edg[N * 2];int res = 0;
int n, m;
int cnt = 0;//并查集找祖宗
int find(int a)
{if(p[a] != a) p[a] = find(p[a]);return p[a];
}void klskr()
{//依次嘗試加入每條邊for(int i = 1; i <= m; i++){int pa = find(edg[i].a);// a 點所在的集合int pb = find(edg[i].b);// b 點所在的集合//如果 a b 不在一個集合中if(pa != pb){res += edg[i].w;//a b 之間這條邊要p[pa] = pb;// 合并a bcnt ++; // 保留的邊數量+1}}
}int main()
{cin >> n >> m;for(int i = 1; i <= n; i++) p[i] = i;//初始化并查集//讀入每條邊for(int i = 1; i <= m; i++){int a, b , c;cin >> a >> b >>c;edg[i] = {a, b, c};}sort(edg + 1, edg + m + 1);//按邊長排序klskr();//如果保留的邊小于點數-1,則不能連通if(cnt < n - 1) {cout<< "impossible";return 0;}cout << res;return 0;
}

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

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

相關文章

遼寧博學優晨教育視頻:引領安全可靠的學習新風尚

在數字化時代&#xff0c;隨著信息技術的飛速發展&#xff0c;線上教育已成為越來越多人提升自我、拓寬視野的重要選擇。遼寧博學優晨教育視頻憑借其安全可靠的特質&#xff0c;在眾多在線教育平臺中脫穎而出&#xff0c;成為廣大學子信賴的學習伙伴。 一、遼寧博學優晨教育視頻…

MagiskHideProps 使用 props 開啟 android 手機的 ro.debuggable =1 的方法

因為 CDSN 一直不給對舊的文章&#xff08;特別是邊幅比較長的文章&#xff09;一直都無法修改&#xff0c;保存&#xff0c;重新發布 一直都是操作超時 我這里是補全 這邊文章中 unity shader - 圣斗士星矢 人物 shader 還原 - GPA 抓幀提取資源、shader&#xff0c;ROOT權…

python 使用curl_cffi 繞過jax3指紋-Cloudflare 5s盾

現在越來越多的網站已經能夠通過JA3或者其他指紋信息&#xff0c;來識別你是不是爬蟲了。傳統的方式比如換UA&#xff0c;加代理是沒有任何意義了&#xff0c;所以這個時候我們就需要使用到curl_cffi 了。 1.TLS 指紋是啥&#xff1f; 在絕大多數的網站都已經使用了 HTTPS&am…

構造pop鏈

反序列化視頻筆記 第一步&#xff1a;找到目標觸發echo調用$flag 第二步&#xff1a;觸發_invoke函數調用appeng函數$varflag.php&#xff08;把對象當成函數&#xff09; 第三步&#xff1a;給$p賦值為對象&#xff0c;即function成為對象Modifier卻被當成函數調用&#xff…

加密與安全_探索口令加密算法(PBE)

文章目錄 概述疑問PBE 算法 &#xff08; Password Based Encryption&#xff09;CodePOM實現 小結 概述 加密與安全_探索對稱加密算法中我們提到AES加密密鑰長度是固定的128/192/256位&#xff0c;而不是我們用WinZip/WinRAR那樣&#xff0c;隨便輸入幾位都可以。 這是因為對…

2024最新算法:斑翠鳥優化算法(Pied Kingfisher Optimizer ,PKO)求解23個基準函數

一、斑翠鳥優化算法 斑翠鳥優化算法&#xff08;Pied Kingfisher Optimizer ,PKO&#xff09;&#xff0c;是由Abdelazim Hussien于2024年提出的一種基于群體的新型元啟發式算法&#xff0c;它從自然界中觀察到的斑翠鳥獨特的狩獵行為和共生關系中汲取靈感。PKO 算法圍繞三個不…

【Ubuntu操作系統】講解

Ubuntu操作系統 1. 前言2. 系統更新3. 安裝編譯工具4. 安裝文本編輯器4.1 Vim4.2 Visual Studio Code 5. 安裝開發庫6. 安裝版本控制系統6.1 Git 7. 安裝數據庫7.1 MySQL7.2 PostgreSQL 8. 安裝編程語言環境8.1 Python8.2 Node.js 9. 安裝其他常用軟件9.1 Chrome瀏覽器9.2 Dock…

MySQL數據庫引擎,以及常用引擎的區別

先看圖&#xff1a; mysql常用引擎包括&#xff1a;MYISAM、Innodb、Memory、MERGE MYISAM&#xff1a; 全表鎖&#xff0c;擁有較高的執行速度&#xff0c;不支持事務&#xff0c;不支持外鍵&#xff0c;并發性能差&#xff0c;占用空間相對較小&#xff0c;對事務完整性沒有…

SpringBoot整合rabbitmq-主題交換機隊列(四)

說明&#xff1a;Topic主題交換機它的大致流程是交換機和一個或者多個隊列綁定&#xff0c;這個綁定的Routingkey是包含通配符的&#xff0c;滿足通配符的隊列會接收到消息。 通配符規則&#xff1a; #&#xff1a;匹配一個或多個詞 *&#xff1a;匹配一個詞 例如&#xff…

2024洗地機深度測評推薦,洗地機哪款值得入手?新手入門必看洗地機選購技巧

洗地機是近年來備受矚目的智能家居產品&#xff0c;它能夠有效地幫助我們節省勞動時間&#xff0c;高效清潔地面&#xff0c;從而減輕我們的勞動負擔。洗地機實現了掃地和拖地的一體化功能&#xff0c;在掃地的同時還能順便完成地面的拖洗工作。配備水箱的設計使得不再需要頻繁…

【kubernetes VPA】記錄一次安裝 VPA 相關組件的報錯解決過程

文章目錄 1. 問題描述2. 問題原因3. 解決辦法4. 參考鏈接 1. 問題描述 在執行 ./hack/vpa-up.sh腳本命令時&#xff0c;提示有報錯。名為vpa-admission-controller的容器狀態一直停留在ContainerCreating&#xff0c;從該Pod詳細描述中得知&#xff0c;volume "tls-certs…

內核參數調優

默認的Linux內核參數考慮的是最通用場景&#xff0c;不符合用于支持高并發訪問的Web服務器的定義&#xff0c;根據業務特點來進行調整&#xff0c;當Nginx作為靜態web內容服務器、反向代理或者提供壓縮服務器的服務器時&#xff0c;內核參數的調整都是不同的&#xff0c;此處針…

【牛客】SQL131 作答試卷得分大于過80的人的用戶等級分布

描述 現有用戶信息表user_info&#xff08;uid用戶ID&#xff0c;nick_name昵稱, achievement成就值, level等級, job職業方向, register_time注冊時間&#xff09;&#xff1a; iduidnick_nameachievementleveljobregister_time11001牛客1號31007算法2020-01-01 10:00:00210…

常見外設學習以及無線通信頻率

常見外設 UART UART&#xff08;Universal Asynchronous Receiver/Transmitter&#xff0c;通用異步收發器&#xff09;是一種異步、串行、全雙工的通信總線。 UART 有3根線&#xff0c;分別是&#xff1a;發送線&#xff08;TX&#xff09;、接收線&#xff08;RX&#xff…

AT24C1024的模擬IIC驅動

AT24C1024是基于IIC的EEPROM&#xff0c;容量為1024/8128k bytes。它的引腳如下&#xff1a; 其中A1,A2為硬件地址引腳 WP為寫保護引腳&#xff0c;一般我們需要讀寫&#xff0c;需要接低電平GND&#xff0c;接高的話則僅允許讀 SDA和SCL則為IIC通信引腳 芯片通信采用IIC&…

02、MongoDB -- MongoDB 的安全配置(創建用戶、設置用戶權限、啟動安全控制、操作數據庫命令演示、mongodb 的幫助系統介紹)

目錄 MongoDB 的安全配置演示前準備&#xff1a;啟動 mongodb 服務器 和 客戶端 &#xff1a;1、啟動單機模式的 mongodb 服務器2、啟動 mongodb 的客戶端 MongoDB 的安全配置啟動演示用到的 mongodb 服務器 和 客戶端啟動單機模式的 mongodb 服務器&#xff1a;啟動 mongodb 的…

【數據結構】19 平衡二叉樹

定義 平衡二叉樹又稱為AVL樹&#xff0c;是具有以下性質的非空搜索樹&#xff1a; 任一結點的左、右子樹均為AVL樹。根節點的左、右子樹高度差的絕對值不超過1. 對于二叉樹的任一結點T&#xff0c;其平衡因子&#xff08;BF&#xff09;定義為BF(T) h L ? h R h_L- h_R hL…

acwing算法提高之搜索--雙向廣搜BFS與A星算法

目錄 1 專題說明2 訓練 1 專題說明 本專題用來記錄使用雙向廣搜BFS和A星算法求解的題目。 2 訓練 題目1&#xff1a;190字串變換 考點&#xff1a;從起點開始搜&#xff0c;從終點開始搜&#xff0c;即雙向廣搜。 C代碼如下&#xff0c; #include <iostream> #incl…

攻防世界-get_post

題目信息 相關知識 -G&#xff1a;表示GET請求&#xff0c;缺省POST -d參數用于發送 POST 請求的數據體 使用-d參數以后&#xff0c;HTTP 請求會自動加上標頭Content-Type : application/x-www-form-urlencoded。并且會自動將請求轉為 POST 方法&#xff0c;因此可以省略-X PO…

使用GPTQ進行4位LLM量化

使用GPTQ進行4位LLM量化 最佳腦量化GPTQ算法步驟1:任意順序洞察步驟2:延遲批量更新第三步:喬爾斯基重塑 用AutoGPTQ量化LLM結論References 權重量化的最新進展使我們能夠在消費級硬件上運行大量大型語言模型&#xff0c;例如在RTX 3090 GPU上運行LLaMA-30B模型。這要歸功于性能…