『算法-ACM竞赛-疯子的算法总结』10 最小生成树Kruscal

『算法-ACM 竞赛-疯子的算法总结』10 最小生成树 Kruscal

疯子的算法总结 10–最小生成树 Kruscal

按照权值排序可得,就有如下顺序:

1. 1-2 1

2. 1-4 2

3. 1-5 2

4. 2-5 3

5. 2-3 4

6. 4-5 4

每次选取最小边泉,判断是否同属一个集合,如果不属于同一集合,就把它加到左端点集合中,也就是说,两个点不属于一个集合说明这条边不在树中,即可将其加入左端点集合。

下面我们模拟算法过程:

每次,直接把每次找到的边找到,就可以了!

对于 Kruscal 它更适合于稀疏图,借助贪心与并查集实现,我们看懂了上述算法实现过程,很容易写出算法!

代码实现

#include<iostream>
#include<queue>
#include<algorithm>
#include<set>
#include<cmath>
#include<vector>
#include<map>
#include<stack>
#include<bitset>
#include<cstdio>
#include<cstring>
//---------------------------------Sexy operation--------------------------//

#define cini(n) scanf("%d",&n)
#define cinl(n) scanf("%lld",&n)
#define cinc(n) scanf("%c",&n)
#define cins(s) scanf("%s",s)
#define coui(n) printf("%d",n)
#define couc(n) printf("%c",n)
#define coul(n) printf("%lld",n)
#define debug(n) printf("%d_________________________________\n",n);
#define speed ios_base::sync_with_stdio(0)
#define file  freopen("input.txt","r",stdin);freopen("output.txt","w",stdout)
//-------------------------------Actual option------------------------------//
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define Swap(a,b) a^=b^=a^=b
#define Max(a,b) (a>b?a:b)
#define Min(a,b) a<b?a:b
#define mem(n,x) memset(n,x,sizeof(n))
#define mp(a,b) make_pair(a,b)
#define pb(n)  push_back(n)
#define dis(a,b,c,d) ((double)sqrt((a-c)*(a-c)+(b-d)*(b-d)))
//--------------------------------constant----------------------------------//

#define INF  0x3f3f3f3f
#define esp  1e-9
#define PI   acos(-1)
using namespace std;
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef  long long ll;
//___________________________Dividing Line__________________________________/

int n,m;
int father[1100000];
struct node
{
    int x;
    int y;
    int k;
}Q[1100000];
int find(int x)
{
    if(father[x]==x)
    return x;
    return father[x]=find(father[x]);
}
bool cmp(node a,node b)
{
    return a.k<b.k;
}
int main()
{
    while(~scanf("%d %d",&n,&m))
    {
        int cont=0,sum=0,st=0;
        for(int i=0;i<m;i++)
        {
            scanf("%d %d %d",&Q[i].x,&Q[i].y,&Q[i].k);
            cont+=Q[i].k;
        }
        sort(Q,Q+m,cmp);
        for(int i=1;i<=n;i++) father[i]=i;
        for(int i=0;i<m;i++)
        {
            int tx=find(Q[i].x);
            int ty=find(Q[i].y);
            if(tx!=ty)
            {
                sum+=Q[i].k;
                st++;
                father[tx]=ty;
                if(st==n-1)
                break;
            }
        }
       printf("%d\n",sum);
    }
    return 0;
}

『算法-ACM竞赛-疯子的算法总结』10 最小生成树Kruscal
https://chiamzhang.github.io/2024/06/29/『算法-ACM竞赛-疯子的算法总结』10 最小生成树Kruscal/
Author
Chiam
Posted on
June 29, 2024
Licensed under