贪心---克鲁斯卡尔算法--最小生成树


#最小生成树---克鲁斯卡尔算法
#include <iostream>
#include<bits/stdc++.h>
#include <queue>
using namespace std;
struct Edge
{
    int x, y;
    int weight;
    bool operator<(const Edge &e) const
    {
        return weight > e.weight;
    }
    Edge(){};
    Edge(int a, int b, int c)
    {
        x = a;
        y = b;
        weight = c;
    }
}edge[1000];
int uf[1000];
int sum=0;
int uf_find(int x)
{
    if(uf[x]<0)
        return x;
    else
        return uf_find(uf[x]);
}
bool uf_union(int x, int y)
{
    int xroot = uf_find(x);
    int yroot = uf_find(y);
    if(xroot == yroot)
        return false;
    uf[yroot] = xroot;
    return true;
}
void kruskal(int v,int e)
{
    int n = 1;
    priority_queue<Edge> Q;
    for(int i=1;i<=e;i++)
        Q.push(Edge(edge[i].x,edge[i].y,edge[i].weight));
    while(!Q.empty() && n < v)
    {
        Edge e = Q.top();
        Q.pop();
        if(uf_union(e.x, e.y))
        {
            sum=sum+e.weight;
            cout << e.x << " " << e.y << " " << e.weight << endl;
            n++;
        }
    }
}
int main()
{
    memset(uf, -1, sizeof(uf));
    int v, e;
    cout<<"输入顶点和边的个数"<<endl;
    cin >> v >> e;
    cout<<"输入边的定点和权值"<<endl;
    for(int i=1;i<=e; i++)
    {
        cin >> edge[i].x >> edge[i].y >> edge[i].weight;
    }
    cout<<endl;
    cout<<"输出选中的边"<<endl;
    kruskal(v,e);
    cout<<"权值"<<sum<<endl;
}

测试数据
7 12
1 2 2
1 4 1
1 3 4
2 5 10
2 4 3
5 4 7
5 7 6
7 4 4
7 6 1
6 4 8
6 3 5
3 4 2
最小生成树的权值和:16

改变并查集之后

#include<iostream>
#include<queue>
#include<bits/stdc++.h>
using namespace std;
struct Edge
{
    int x,y;
    int w;
    bool operator <(const Edge & e) const
    {
        return w>e.w;
    }
    Edge() {};
    Edge(int a,int b,int c)
    {
        x=a;
        y=b;
        w=c;
    }
} edge[1000];
int pre[1000];
int sum=0;
int findd(int x)
{
    int r=x;
    while(r!=pre[r])
        r=pre[r];
    int i=x;
    int j;
    while(i!=r)
    {
        j=pre[i];
        pre[i]=r;
        i=j;
    }
    return r;
}
bool unionn(int x,int y)
{
    if(findd(x)==findd(y))
        return false;
    pre[findd(x)]=findd(y);
    return true;
}

void kruskal(int e,int v)
{
    int n=1;
    priority_queue<Edge> Q;
    for(int i=1; i<=e; i++)
        Q.push(Edge(edge[i].x,edge[i].y,edge[i].w));
    while(n<v&&!Q.empty())
    {
        Edge h=Q.top();
        Q.pop();
        if(unionn(h.x,h.y))
        {
            sum=sum+h.w;
            cout<<h.x<<" "<<h.y<<" "<<h.w<<endl;
            n++;
        }
    }
}
int main()
{
    int v,e;
    cout<<"输入顶点数和边数"<<endl;
    cin>>v>>e;
    for(int i=1; i<=e; i++)
        pre[i]=i;
    cout<<"输入各条边的顶点和权重"<<endl;
    for(int i=1; i<=e; i++)
    {
        cin>>edge[i].x>>edge[i].y>>edge[i].w;
    }
    cout<<endl;
    cout<<"输出选择的边"<<endl;
    kruskal(e,v);
    cout<<"输出总权重"<<sum<<endl;
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值