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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

最小树 次小树 模板

發(fā)布時(shí)間:2025/6/17 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 最小树 次小树 模板 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
最小生成樹
?
? ? ?兩種算法,Kruskal 和 Prim ;


? ? ?Kruskal 是針對(duì)于稀疏圖的,因?yàn)樗膹?fù)雜度是跟邊有關(guān)系的;
? ? ?先sort一便,然后用并查集加邊就行了,簡(jiǎn)單沒(méi)什么說(shuō)的.
?
? ? ?Prim 是針對(duì)于稠密圖的,這個(gè)算法自己很少用,就是每次都找到加入后邊最小的那個(gè)點(diǎn)


加進(jìn)來(lái)就行了,前兩天hdu4756逼得我不得不看這個(gè)算法.


? ??
次小樹


? ?次小樹自己常用的也是兩種算法,不知道名字,可能算不上是什么算法吧
? ?先說(shuō)一下思想吧,次小樹其實(shí)就是先找到一顆最小樹,然后刪除其中一條邊,找到一個(gè)最有


的可以連接兩個(gè)集合的邊就行了,更新到最后就是次小樹,其實(shí)也可以這樣,先跑一邊最小樹,
然后枚舉所有不是最小樹上的邊,想下,如果這條邊加在最小樹里肯定會(huì)產(chǎn)生環(huán),所以直接找


到環(huán)中最長(zhǎng)的邊(該邊除外)減去就行了,這樣更新到最后也是次小樹,這就是第二種方法,第


一種方法中的找最小可以用樹形dp去優(yōu)化,如果暴力時(shí)間復(fù)雜度肯能會(huì)到o(n^3);


下面是模板


Kruskal






#include<algorithm>


#define MAX_EDGE 10000//邊的最大個(gè)數(shù)?
#define MAX_NODE 1000//點(diǎn)的最大個(gè)數(shù)
?
using namespace std;


typedef struct
{
? ?int a ,b;
? ?double dis;
}EDGE;


EDGE edge[MAX_EDGE]; //把邊存到這里?
int mer[MAX_EDGE];
?
bool camp(EDGE a ,EDGE b)
{
? ?return a.dis < b.dis;
}


int finds(int x)
{ ??
? ?return x == mer[x] ? x : mer[x] = finds(mer[x]);
}


struct KRUSKAL
{
? ?double Kruskal (int edge_n ,int node_n)//邊和點(diǎn)的個(gè)數(shù)?
? ?{
? ? ? double ans; ??
? ? ? sort(edge + 1 ,edge + edge_n + 1 ,camp);
? ? ? for(int i = 0 ;i <= node_n ;i ++) mer[i] = i;
? ? ? ans = 0;
? ? ? for(int i = 1 ;i <= edge_n ;i ++)
? ? ? {
? ? ? ? ?int x = finds(edge[i].a);
? ? ? ? ?int y = finds(edge[i].b);
? ? ? ? ?if(x == y) continue;
? ? ? ? ?mer[x] = y;
? ? ? ? ?ans += edge[i].dis;
? ? ? }
? ? ? return ans;?
? ?}
}K;
? ?


Prim


struct PRIM //從0開始用?
{ ? ? ? ? ??
? ?double d[N];int vis[N]; ?
? ?bool mp[N][N]; ?//標(biāo)記最小生成樹上的邊?
? ?double ans;//最小樹?
? ?int n;//點(diǎn)的個(gè)數(shù) ? ? ? ? ? ? ? ? ? ? ? ? ? 記得初始化 ? ?***
? ?double dis[N][N]; // 距離 ? ? ? ? ? ? ? ? ?記得初始化 ?*****
? ?
? ?
void prim()
{?
? ? for(int i=0;i<n;i++)
? ? { ?
? ? ? ? vis[i]=0; ?
? ? ? ? d[i]=dis[0][i]; ?
? ? } ?
? ? vis[0]=-1; ?
? ? ans=0; ?
? ? memset(mp,0,sizeof(mp)); ?
? ? for(int i=1;i<n;i++)
? ? { ?
? ? ? ? double Min= inf; ?
? ? ? ? int node=-1; ?
? ? ? ? for(int j=0;j<n;j++)
? ? ? ? { ?
? ? ? ? ? ? if(vis[j]!=-1 && d[j]<Min)
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? node=j; ?
? ? ? ? ? ? ? ? Min=d[j]; ?
? ? ? ? ? ? } ?
? ? ? ? } ?
??
? ? ? ? ans+=Min; ?//printf("%lf\n" ,ans); ?
? ? ? ? mp[vis[node]][node]=mp[node][vis[node]]=1; ?
? ? ? ? //add(vis[node],node); // 建樹 ?
? ? ? ? vis[node]=-1; ?
??
? ? ? ? for(int j=0;j<n;j++)
? ? ? ? { ?
? ? ? ? ? ? if(vis[j]!=-1 && d[j]>dis[node][j])
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? vis[j]=node; ?
? ? ? ? ? ? ? ? d[j]=dis[node][j]; ?
? ? ? ? ? ? } ?
? ? ? ? } ?
? ? } ?
?}
}P;




剩下的那兩個(gè) 還沒(méi)有總結(jié)好模板,最近也正在學(xué),學(xué)完在總結(jié)補(bǔ)上吧..
? ? ?
? ??

總結(jié)

以上是生活随笔為你收集整理的最小树 次小树 模板的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。