1. 程式人生 > 實用技巧 >最好用的輪播外掛——Swiper.js

最好用的輪播外掛——Swiper.js

prim

先將一個點加入集合中,維護一個dis陣列,表示該點距集合中的點的最小距離,每次選取dis的最小值,並把那個點加入集合,更新dis。

可以用優先佇列優化

kruskal

把所有的邊按邊權從小到大排序,利用並查集維護集合關係,對於每條邊,若兩點不在同一集合,則把兩點連線。

Boruvka

假設每個點都是一個聯通塊,然後求出與當前聯通塊最近的一個聯通塊的距離,然後讓兩個塊聯通

#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define pii pair<int,int>
const int inf = 0x3f3f3f3f;
const int maxn = 201110;
const int M = 1e9+7;
int n,m,k,ok;

vector<pii> v[maxn];

int pre[maxn],sz[maxn];     //記錄聯通塊大小

int find(int x)
{
    return x==pre[x]?x:pre[x]=find(pre[x]);
}

void unite(int x,int y)
{
    x = find(x);
    y = find(y);
    if(x == y) return;
    pre[x] = y;
    sz[y] += sz[x];
}

int link[maxn],val[maxn];

void Boruvka()
{
    for(int i = 1; i <= n; i++) 
    {
        pre[i] = i,sz[i] = 1;
    }
    int ans = 0;
    bool flag;
    do
    {
        flag = 0;
        mem(link,0);mem(val,0x3f);
        for(int i = 1; i <= n; i++)        
        {
            int x = find(i);
            for(auto j : v[i])
            {
                int y = find(j.first);
                if(x == y || j.second > val[x]) continue;       //如果當前聯通快和其他聯通快之間有更短的邊
                link[x] = y;val[x] = j.second;
            }
        }
        for(int i = 1; i <= n; i++) 
        {
            int x = find(i);
            if(!link[x] && find(x) != find(link[x]))
            {
                unite(x,link[x]);
                flag = 1;
                ans += val[x];
            }
        }
    } while (flag);
    int x = find(1);
    if(sz[x] != n) ans = -1;        //不聯通
    cout<<ans<<endl;
}

signed main()
{
    cin>>n>>m;
    for(int i = 1,x,y,z; i <= m; i++) 
    {
        cin>>x>>y>>z;
        v[x].push_back({y,z});
        v[y].push_back({x,z});
    }
    Boruvka();
    return 0;
}