1. 程式人生 > >最小生成樹-Kruskal演算法(模板)

最小生成樹-Kruskal演算法(模板)

Kruskal基本演算法:每次選取最短的邊,看該邊相連的兩點是否在同一集合內,若在,則跳過,若不在,就把兩個點合併,判斷與合併都用並查集實現。

Kruskal的複雜度是O(ElogE),適合稀疏圖。

/*
Kruskal演算法求MST
*/

#include<iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
#include<fstream>
using namespace std;

const int MAXN=505;//最大點數
const int MAXM=250005;//最大邊數
int F[MAXN];//並查集使用

struct Edge
{
    int u,v,w;
}edge[MAXM];//儲存邊的資訊,包括起點/終點/權值

int tol;//邊數,加邊前賦值為0

void addedge(int u,int v,int w)
{
    edge[tol].u=u;
    edge[tol].v=v;
    edge[tol++].w=w;
}

bool cmp(Edge a,Edge b)//排序函式,邊按照權值從小到大排序
{
    return a.w<b.w;
}

int Find(int x)
{
    if(F[x]==-1)
        return x;
    else
        return F[x]=Find(F[x]);
}

int Kruskal(int n)//傳入點數,返回最小生成樹的權值,如果不連通返回-1
{
    memset(F,-1,sizeof(F));
    sort(edge,edge+tol,cmp);
    int cnt=0;//計算加入的邊數
    int ans=0;
    for(int i=0;i<tol;i++)
    {
        int u=edge[i].u;
        int v=edge[i].v;
        int w=edge[i].w;
        int t1=Find(u);
        int t2=Find(v);
        if(t1!=t2)
        {
            ans+=w;
            F[t1]=t2;
            cnt++;
        }
        if(cnt==n-1)
            break;
    }
    if(cnt<n-1)
        return -1;//不連通
    else
        return ans;
}

int main()
{
    //freopen("in.txt","r",stdin);
    int T;
    cin>>T;
    int n;
    int c;
    while(T--)
    {
        cin>>n;
        tol=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                cin>>c;
                addedge(i,j,c);
            }
        }
        cout<<Kruskal(n)<<endl;
    }
    return 0;
}


相關推薦

小生成樹-Kruskal演算法模板

Kruskal基本演算法:每次選取最短的邊,看該邊相連的兩點是否在同一集合內,若在,則跳過,若不在,就把兩個點合併,判斷與合併都用並查集實現。 Kruskal的複雜度是O(ElogE),適合稀疏圖。

1251 Jungle Roads 小生成樹Kruskal演算法模板

Kruskal演算法比Prim更好寫#include<iostream> #include<cstdio> #include<algorithm> #define

小生成樹prim演算法模板

prim演算法適合稠密圖,即邊數較多而點較少的情況,時間複雜度為O(n2)O(n2),堆優化的情況下,如果點數為m,邊數為n,可以達到O(nlogm)O(nlogm).思想很簡單,就是每次尋找一條由已加入集合的點和與它們相鄰的沒加入集合的點的權值最小邊,進行n-

小生成樹-kruskal演算法非並查集的實現&優先佇列的sh xian&並查集的實現

kruskal演算法:構造一個只含n個頂點,而邊集為空的子圖,若將該子圖中各個頂點看成是各棵樹的根節點,則它是一個含有n棵樹的森林 。之後,從網的邊集中選取一條權值最小的邊,若該邊的兩個頂點分屬不同的樹 ,則將其加入子圖,也就是這兩個頂點分別所在的 兩棵樹合成一棵樹;反之,若該邊的兩個頂點已落在同一

Java資料結構和演算法小生成樹---Kruskal演算法並查集

該文章利用prime演算法求得連通圖的最小生成樹對應的邊權最小和,prime演算法是從頂點的角度思考和解決問題。本文介紹的Kruskal演算法將從邊的角度考慮並解決問題,利用了並查集方便地解決了最小生成樹的問題。 本文參考博文 //並查集 class UnionSameSet{

小生成樹kruskal演算法貪心+並查集+堆優化

kruskal演算法克魯斯卡爾演算法的基本思想是以邊為主導地位,始終選擇當前可用(所選的邊不能構成迴路)的最小權植邊。所以Kruskal演算法的第一步是給所有的邊按照從小到大的順序排序。這一步可以直接使用庫函式qsort或者sort。接下來從小到大依次考察每一條邊(u,v)。

圖的廣度遍歷、深度遍歷及小生成樹演算法Prim、Kruskal

typedef struct { char vertex[VertexNum]; //頂點表 int edges[VertexNum][VertexNum];

模板--小生成樹 Kruskal 演算法不詳解

最小生成樹   是由n個節點的連通圖變化來的。這棵樹滿足如下條件:     1、是原來圖的子圖(原來的圖扣去了幾條邊)     2、在保證圖仍然連通的情況下,剩下的邊權和是最小的     3、滿足樹的性質   最小生成樹常用來解決這樣的問題:     有n個村莊,他們之間本沒有路(走的人多了就有路了)。我們現

CodeForces 609 E.Minimum spanning tree for each edge小生成樹-Kruskal+線上倍增LCA

Description 給出一個n個點m條邊的無向連通圖,對於每一條邊,問包含該條邊的最小生成樹權值和 Input 第一行兩個整數n和m表示點數和邊數,之後m行每行三個整數u,v,w表示u和v之間有一條邊權為w的邊(1<=n<=2e5,n-1&

CodeForces 733 F.Drivers Dissatisfaction小生成樹-Kruskal+線上倍增法

Description 給出n個點m條邊,每條邊有邊權,第i條邊邊權為w[i],可以花費c[i]使得第i條邊邊權減一,在花費不超過S的情況下求最小生成樹 Input 第一行兩個整數n和m分別表示點數和邊數,之後m個整數w[i]表示第i條邊的邊權,之後m個整

小生成樹 prim演算法附程式碼

prim演算法是以一個根節點開始慢慢往下延伸,不斷尋找距生成樹最短的距離的節點,然後將該節點納入生成樹的集合中,然後再將該節點影響的其他未納入生成樹節點的距離更新。(縮小與生成樹的距離),重複操作,直至全部節點納入集合或者沒有節點納入集合為止。 prim演算法的時間複雜度為

【Codevs1078】小生成樹 Prim演算法5/1000

Description Farmer John has been elected mayor of his town! One of his campaign promises was to bring internet connectivity to all

圖的小生成樹Kruskal演算法

克魯斯卡爾(Kruskal)演算法(只與邊相關) 演算法描述:克魯斯卡爾演算法需要對圖的邊進行訪問,所以克魯斯卡爾演算法的時間複雜度只和邊又關係,可以證明其時間複雜度為O(eloge)。 演算法過程: 1.將圖各邊按照權值進行升序排序 2.將圖遍歷一次,找出權值最小的邊,(條件

小生成樹 - Kruskal演算法

Kruskal演算法 第二種最小生成樹演算法 —— Kruskal演算法 按照邊的權重順序(從小到大)處理它們,將邊加入最小生成樹中,加入的邊不會與已經加入的邊構成環,直到樹中含有 V

圖之小生成樹 Kruskal演算法 Prim演算法

一.實際問題 最小生成樹一般應用在網(帶權的圖)問題中,實際問題一般比如:   假設要在n個城市間建立通訊聯絡網,則聯通n個城市只需要n-1條線路,但是每兩個城市間都可以建設路線,而且城市與城市間建設代價是不同的,這就需要我們考慮一種經濟的聯絡方式。 將問

資料結構實驗之圖論六:村村通公路——小生成樹Kruskal演算法

Think: 1知識點:最小生成樹Kruskal演算法(並查集思想) 2反思:注意變數初始化 以下為Accepted程式碼 #include <bits/stdc++.h> using namespace std; struct

10-25 小生成樹——kruskal演算法學習——經典例題及自編模版

---------------題目--------------- 1078 最小生成樹  時間限制: 1 s  空間限制: 128000 KB  題目等級 : 白銀 Silver 題解 題目描述 Description

小生成樹---Kruskal演算法---挑戰程式設計競賽讀書筆記

測試資料也一樣。 這個演算法用到並查集來高效的判斷頂點u,v是否屬於同一個聯通分量。 程式碼: #include <iostream> #include <cstring> #include <cstdlib> #include &

圖的小生成樹kruskal演算法總結

kruskal演算法的思想 假如N={V,{E}}是連通網,那麼最小生成樹的初始狀態是由V個頂點自成連通分量構成的一片森林。在E中選擇權值最小的邊,當該邊對應的兩個頂點在不同分量時,則將該邊加入到最小生成樹中,否則的捨去,再選擇下一條代價最小的邊,如此迴圈,直到所有的連通

小生成樹 Kruskal演算法

關於最小生成樹的概念,請參考前一篇文章:Prim演算法。 Kruskal演算法: 不停地迴圈,每一次都尋找兩個頂點,這兩個頂點不在同一個真子集裡,且邊上的權值最小。 把找到的這兩個頂點聯合起來。 初始時,每個頂點各自屬於自己的子集合,共n個子集合。 每