最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++實(shí)現(xiàn)基于不相交集合的O(mlgn)復(fù)雜度的kruskal算法

 更新時(shí)間:2023年02月22日 14:46:17   作者:Shawn-Summer  
這篇文章主要為大家詳細(xì)介紹了C++如何實(shí)現(xiàn)基于不相交集合的O(mlgn)復(fù)雜度的kruskal算法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下

C++實(shí)現(xiàn)基于不相交集合的O(mlgn)復(fù)雜度的kruskal算法

本文實(shí)現(xiàn)完全參考<<Introduction to Algorithms Third edition>>,

不相交集合的數(shù)據(jù)結(jié)構(gòu)

我們采用森林的方式實(shí)現(xiàn)不相交集合。這個(gè)森林是極簡(jiǎn)化的,每個(gè)節(jié)點(diǎn)只有一個(gè)指向父親的指針,而且森林中的每一顆樹(shù)都是一個(gè)集合,我們?nèi)?shù)的根節(jié)點(diǎn)為這個(gè)集合的代表元。

int rank[505];
int father[505];
void make_set(int x)
{
	father[x]=x;
	rank[x]=0;
}
int find_set(int x)
{
    if (x!=father[x])
    {
        father[x]=find_set(father[x]);
    }
    return father[x];
}
void simply_union_set(int u,int v)
{
    u=find_set(u);
    v=find_set(v);
    father[u]=v;
}
void  perfect_union_set(int u,int v)
{
    u=find_set(u);
    v=find_set(v);
    if (rank[u]>rank[v])
    {
        father[v]=u;
    }
    else
    {
        father[u]=v;
        if(rank[u]==rank[v])
        rank[v]++;
    }

}

可以看到在find_set()函數(shù)中采用了兩趟遍歷的思想,第一趟遍歷找的根節(jié)點(diǎn),第二趟遍歷將路徑上的節(jié)點(diǎn)全部指向根節(jié)點(diǎn),完成了壓縮樹(shù)高。

在實(shí)現(xiàn)集合合并的時(shí)候,我們采用了兩種方法:一種方法是直接合并simply_union_set,另一種是采用按秩合并的思想perfect_union_set,即總是讓秩小合并到秩大的集合中,這是一種減少樹(shù)高的有效策略;

當(dāng)我們采用按秩合并時(shí)時(shí),上述每一個(gè)操作的最差時(shí)間復(fù)雜度,都約等于O(1)

詳情見(jiàn)<<Introduction to Algorithms Third edition>>中證明

kruskal 算法

void kruskal()
{
    for(int i=0;i<num_v;i++)make_set(i);
    sort(arr_edge.begin(),arr_edge.end(),mycompare);
    for(int i=0;i<arr_edge.size();i++)
    {
        int fr=arr_edge[i].fr;
        int to=arr_edge[i].to;
        int w=arr_edge[i].w;
        if( find_set(fr)!=find_set(to))
        {
        	result+=w;
            perfect_union_set(fr,to);
        }
    }
}

kruskal 算法是一種基于貪心策略的算法,它的時(shí)間復(fù)雜度的最大開(kāi)銷(xiāo)就是排序算法,即O(mlgm)=O(mlgn),這里m表示邊數(shù),n表示頂點(diǎn)數(shù)

知識(shí)補(bǔ)充

乘勝追擊一下,通過(guò)一個(gè)例題再深入了解一下kruskal 算法吧

題目http://poj.org/problem?id=2485

思路:就是最小生成樹(shù)啊

代碼

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
using namespace std;
#define INTMAX 0x3f3f3f3f
typedef pair<int,int> pii;
typedef long long ll;
#define x first
#define y second

int rank[505];
int father[505];
int find_set(int x)
{
    if (x!=father[x])
    {
        father[x]=find_set(father[x]);
    }
    return father[x];
}
void simply_union_set(int u,int v)
{
    u=find_set(u);
    v=find_set(v);
    father[u]=v;
}
void  perfect_union_set(int u,int v)
{
    u=find_set(u);
    v=find_set(v);
    if (rank[u]>rank[v])
    {
        father[v]=u;
    }
    else
    {
        father[u]=v;
        if(rank[u]==rank[v])
        rank[v]++;
    }

}
struct edge
{
    int fr,to,w;
};
int num_case,num_v,result;
vector<edge> arr_edge;

void debug()
{
    for(int i=0;i<arr_edge.size();i++)
    {
        cout<<arr_edge[i].fr<<" to "<<arr_edge[i].to<<"="<<arr_edge[i].w<<endl;
    }
}

void init()
{
    arr_edge.clear();
    result=0;
}
void input()
{
    int w;
    scanf("%d",&num_v);
    for(int i=0;i<num_v;i++)
    {
        for(int j=0;j<num_v;j++)
        {
            scanf("%d",&w);
            if(i<j)
            {
                edge temp;
                temp.fr=i;
                temp.to=j;
                temp.w=w;
                arr_edge.push_back(temp);
            }
        }
    }

}
bool mycompare(const edge& x,const edge &y)
{
    return x.w<y.w;
}
void kruskal()
{
    for(int i=0;i<num_v;i++)father[i]=i;
    sort(arr_edge.begin(),arr_edge.end(),mycompare);
    for(int i=0;i<arr_edge.size();i++)
    {
        int fr=arr_edge[i].fr;
        int to=arr_edge[i].to;
        int w=arr_edge[i].w;
        if( find_set(fr)!=find_set(to))
        {
            result=max(result,w);
            simply_union_set(fr,to);
        }
    }
}
void solve()
{
    init();
    input();
    //debug();
    kruskal();
    cout<<result<<endl;
}

int main()
{
    scanf("%d",&num_case);
    while(num_case--)
    {
        solve();
    }
    return 0;
}

到此這篇關(guān)于C++實(shí)現(xiàn)基于不相交集合的O(mlgn)復(fù)雜度的kruskal算法的文章就介紹到這了,更多相關(guān)C++ kruskal算法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++面向?qū)ο笳Z(yǔ)言自制多級(jí)菜單功能實(shí)現(xiàn)代碼

    C++面向?qū)ο笳Z(yǔ)言自制多級(jí)菜單功能實(shí)現(xiàn)代碼

    菜單類(lèi)主要負(fù)責(zé)菜單的創(chuàng)建、修改、刪除,是包含菜單結(jié)構(gòu)組織和響應(yīng)函數(shù)的模型,用戶(hù)擁有充分的自主性,可根據(jù)需要自定義菜單顯示和響應(yīng)函數(shù),這篇文章主要介紹了C++面向?qū)ο笳Z(yǔ)言自制多級(jí)菜單,需要的朋友可以參考下
    2024-06-06
  • C++?vector與數(shù)組轉(zhuǎn)換寫(xiě)入/讀出文件方式

    C++?vector與數(shù)組轉(zhuǎn)換寫(xiě)入/讀出文件方式

    這篇文章主要介紹了C++?vector與數(shù)組轉(zhuǎn)換寫(xiě)入/讀出文件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • C語(yǔ)言實(shí)現(xiàn)去除字符串中空格的簡(jiǎn)單實(shí)例

    C語(yǔ)言實(shí)現(xiàn)去除字符串中空格的簡(jiǎn)單實(shí)例

    下面小編就為大家?guī)?lái)一篇C語(yǔ)言實(shí)現(xiàn)去除字符串中空格的簡(jiǎn)單實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-05-05
  • 利用OpenCV實(shí)現(xiàn)綠幕視頻背景替換

    利用OpenCV實(shí)現(xiàn)綠幕視頻背景替換

    這篇文章主要介紹了如何利用OpenCV實(shí)現(xiàn)綠幕視頻背景替換功能,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)OpenCV有一定的幫助,感興趣的可以學(xué)習(xí)一下
    2022-01-01
  • C/C++ ip地址與int類(lèi)型的轉(zhuǎn)換實(shí)例詳解

    C/C++ ip地址與int類(lèi)型的轉(zhuǎn)換實(shí)例詳解

    這篇文章主要介紹了C/C++ ip地址與int類(lèi)型的轉(zhuǎn)換實(shí)例詳解的相關(guān)資料,這里提供了實(shí)例代碼,實(shí)現(xiàn)思路及實(shí)現(xiàn)方法,需要的朋友可以參考下
    2016-12-12
  • C++11中的原子量和內(nèi)存序詳解

    C++11中的原子量和內(nèi)存序詳解

    這篇文章主要給大家介紹了關(guān)于C++11中原子量和內(nèi)存序的相關(guān)資料,文中通過(guò)示例代碼介紹地方非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-06-06
  • C語(yǔ)言常見(jiàn)排序算法之插入排序(直接插入排序,希爾排序)

    C語(yǔ)言常見(jiàn)排序算法之插入排序(直接插入排序,希爾排序)

    這篇文章介紹C語(yǔ)言常見(jiàn)排序算法之插入排序(直接插入排序,希爾排序),主要分享介紹的是插入排序的兩種常用算法,直接插入排序和希爾排序,需要的朋友可以參考一下
    2022-07-07
  • C語(yǔ)言命令行參數(shù)的使用詳解

    C語(yǔ)言命令行參數(shù)的使用詳解

    本文主要介紹了C語(yǔ)言命令行參數(shù)的使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • C語(yǔ)言中怎么在main函數(shù)開(kāi)始前執(zhí)行函數(shù)

    C語(yǔ)言中怎么在main函數(shù)開(kāi)始前執(zhí)行函數(shù)

    C語(yǔ)言中怎么在main函數(shù)開(kāi)始前執(zhí)行函數(shù)呢?下面小編就大家詳細(xì)的介紹一下。需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助
    2013-10-10
  • vs運(yùn)行時(shí)報(bào)C4996代碼錯(cuò)誤的問(wèn)題解決

    vs運(yùn)行時(shí)報(bào)C4996代碼錯(cuò)誤的問(wèn)題解決

    C4996錯(cuò)誤的意思:是VS覺(jué)得strcpy這函數(shù)不安全,建議你使更安全的函數(shù),那么如何解決呢,本文主要介紹了vs運(yùn)行時(shí)報(bào)C4996代碼錯(cuò)誤的問(wèn)題解決,感興趣的可以了解一下
    2024-01-01

最新評(píng)論

石泉县| 夏邑县| 张掖市| 铅山县| 咸丰县| 保山市| 中西区| 吴川市| 兴仁县| 甘谷县| 高邮市| 唐海县| 启东市| 定西市| 綦江县| 宿松县| 固原市| 万州区| 固阳县| 合川市| 丁青县| 扶沟县| 呼图壁县| 乌拉特后旗| 平阳县| 喀什市| 东海县| 高密市| 富民县| 廊坊市| 冀州市| 康定县| 儋州市| 崇左市| 康马县| 泰顺县| 通州区| 司法| 龙州县| 西丰县| 遂昌县|