最小生成树

克鲁斯卡尔算法

适合于求边稀疏的网的最小生成树

思路:

将每条边的权值按从小到大的顺序排列,然后遍历,将边放回图中,如果此时的连线不能形成环,则继续,否则将此边丢弃,直到放进去n-1条边(n个点连通需要n-1条边)结束

 

用结构体存储顶点和边,sort排序

struct bian//存储边的信息
{
    int x,y,w;
}a[maxn];

如何判断是否成环----并查集(https:////www.cnblogs.com/subject/p/12386581.html

如果最终父类相同说明在一个集合中(形成环)

int getfather(int x)//递归找父类
{
    if(father[x]==x) return x;
    father[x] = getfather(father[x]);
    return father[x];
}
void unionm(int x,int y)//合并
{
    int fa,fb;
    fa = getfather(x);
    fb = getfather(y);
    if(fa!=fb) father[fa] = fb;
}
void Init()//父类初始化
{
    for(int i = 1;i <= n;i++)
        father[i] = i;
    return;
};

void Kruskal()
{
    int ans = 0;//记录权值
    int k = 0;//记录已经连几条边
    for(int i=1;i<=m;i++)
    {
        if(getfather(a[i].x)!=getfather(a[i].y))//父类不同,说明是两个集合,此边可取
        {
            unionm(a[i].x,a[i].y);//合并为一个集合
            ans+=a[i].w;//权值相加
            k++;
        }
        if(k==n-1) break;
    }
    if(k==n-1) cout<<ans<<endl;
    else cout<<"impossible"<<endl;//遍历完 也不够n-1条 说明不能形成通路。
}

完整代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5+5;

struct bian//存储边的信息
{
    int x,y,w;
}a[maxn];

int father[maxn];//每个点的最终父类
int n,m;
bool cmp(const bian& a,const bian& b)
{
    return a.w<b.w;
}

int getfather(int x)//递归找父类
{
    if(father[x]==x) return x;
    father[x] = getfather(father[x]);
    return father[x];
}
void unionm(int x,int y)//合并
{
    int fa,fb;
    fa = getfather(x);
    fb = getfather(y);
    if(fa!=fb) father[fa] = fb;
}
void Init()//父类初始化
{
    for(int i = 1;i <= n;i++)
        father[i] = i;
    return;
};

void Kruskal()
{
    int ans = 0;
    int k = 0;
    for(int i=1;i<=m;i++)
    {
        if(getfather(a[i].x)!=getfather(a[i].y))
        {
            unionm(a[i].x,a[i].y);
            ans+=a[i].w;
            k++;
        }
        if(k==n-1) break;
    }
    if(k==n-1) cout<<ans<<endl;
    else cout<<"impossible"<<endl;
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        cin>>a[i].x>>a[i].y>>a[i].w;
    }
    Init();
    sort(a+1,a+1+m,cmp);

    Kruskal();

    return 0;
}
View Code

 

posted @ 2020-03-02 00:02  精神小伙儿  阅读(144)  评论(0编辑  收藏  举报