日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

图论 —— 生成树 —— 增量最小生成树

發布時間:2025/3/17 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 图论 —— 生成树 —— 增量最小生成树 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【概述】

所謂最小增量生成樹問題,即:給定包含 n 個點的空圖,依次加入 m 條帶權邊,每次加入一條邊,就輸出當前圖中最小生成樹的權值,如果沒有生成樹,則輸出無解

求解最小增量生成樹的方法是:根據最小生成樹的回路性質,在原有最小生成樹的基礎上,每次增加一條邊就會構成一個回路,那么去掉這個回路上權值最大的邊,得到的就是新的最小生成樹。

簡單來說,每一次加邊之前先跑一遍 Kruskal 找最小生成樹,若已經有最小生成樹,則新加入的邊肯定會讓其形成環,這時候開始進行刪邊操作,刪去那個多余的邊即可。

【模版】

struct Node {int u,v;int val;bool operator<(const Node& rhs)const {return val<rhs.val;} } edge[N]; int n,m,cnt; int father[N]; int Find(int x) {if(father[x]==x)return x;return father[x]=Find(father[x]); } void Kruskal() {sort(edge,edge+cnt);int pos=-1;int res=0,mst=0;for(int i=0; i<cnt; i++) {int u=edge[i].u,v=edge[i].v;int x=Find(u),y=Find(v);if(x!=y) {father[x]=y;res++;mst+=edge[i].val;} else {pos=i;continue;}}if(pos!=-1) edge[pos]=edge[--cnt];if(res!=n-1)printf("-1\n");elseprintf("%d\n",mst); } int main() {scanf("%d%d",&n,&m);cnt=0;for(int i=0; i<m; i++) {//添m次邊scanf("%d%d%d",&edge[cnt].u,&edge[cnt].v,&edge[cnt].val);cnt++;for(int i=0; i<N; i++)father[i]=i;Kruskal();//每次添邊跑一次Kruskal}return 0; }

?

總結

以上是生活随笔為你收集整理的图论 —— 生成树 —— 增量最小生成树的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。