最小生成树算法模板

此处不解释算法,只写代码模板。

prim:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAX=0x3f3f3f3f;
int flag[101];//用来标记0和1  表示这个点是否被选择过
int map[101][101];//邻接矩阵用来存储图的信息
int dis[101];//记录任意一点到这个点的最近距离
int n;//点个个数
int prim()
{
    int i,t;
    int sum=0;
    for(i=1; i<=n; i++)   //初始化
    {
        dis[i]=MAX;
        flag[i]=0;
    }
    for(i=1; i<=n; i++)
    {
        dis[i]=map[1][i];   //选定1为起始点,初始化
    }
    dis[1]=0;
    flag[1]=1;
    int T=n-1;       //循环找最小边,循环n-1次
    while(T--)
    {
        t=MAX;
        int min=MAX;
        for(i=1; i<=n; i++)
        {
            if(flag[i]==0&&dis[i]<min)
            {
                t=i;
                min=dis[i];
            }
        }
        if(t==MAX)
            break;//防止不成图
        flag[t]=1;
        sum+=min;
        for(i=1; i<=n; i++)//添入新点后更新最小距离
        {
            if(flag[i]==0&&dis[i]>map[t][i])
                dis[i]=map[t][i];
        }
    }
    if(t==MAX)
        cout<<"?"<<endl;
    else
        cout<<sum<<endl;
}
int main()
{
    int a,b,c,d,m,i;
    while(cin>>n&&n)//n是点数
    {
        m=n*(n-1)/2;//m是边数
        memset(map,MAX,sizeof(map));//map是邻接矩阵存储图的信息
        for(i=1; i<=m; i++)
        {
            cin>>a>>b>>c;
            if(c<map[a][b])//防止重边
                map[a][b]=map[b][a]=c;
        }
        prim();
    }
}

Kruskal算法

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n, m,sum;
struct node
{
    int start;
    int end;
    int power;//start为起始点,end为终止点,power为权值
} edge[5050];
int pre[5050];
bool cmp(struct node a,struct node b)
{
    return a.power<b.power;//按照权值排序
}
int find(int x)//并查集找祖先
{
    if(x!=pre[x])
        pre[x]=find(pre[x]);
    return pre[x];
}
void merge(int x,int y,int i)//并查集合并函数,n是用来记录最短路中应该加入哪个点
{
    int fx=find(x);
    int fy=find(y);
    if(fx!=fy)
    {
        pre[fx]=fy;
        sum+=edge[i].power;
    }
}
int main()
{
    while(cin>>n&&n)//n是点数
    {
        sum=0;
        m=n*(n-1)/2;//m是边数,可以输入
        int i;
        int start,end,power;
        for(i=1; i<=m; i++)
        {
            cin>>start>>end>>power;
            edge[i].start=start,edge[i].end=end,edge[i].power=power;
        }
        for(i=1; i<=m; i++)
        {
            pre[i]=i;
        }//并查集初始化
        sort(edge+1, edge+m+1,cmp);  //对权值进行排序
        for(i=1; i <= m; i++)
        {
            merge(edge[i].start,edge[i].end,i);
        }
        cout<<sum<<endl;
    }
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值