1075: 求最小生成树(Prim算法)

题目描述
求出给定无向带权图的最小生成树。图的定点为字符型,权值为不超过100的整形。在提示中已经给出了部分代码,你只需要完善Prim算法即可。

题目所给代码如下:

#include<iostream>
using namespace std;
typedef struct
{
    int n;
    int e;
    char data[500];
    int edge[500][500];
}Graph;

typedef struct
{
    int index;
    int cost;
}mincost;

typedef struct
{
    int x;
    int y;
    int weight;
}EDGE;


typedef struct
{
    int index;
    int flag;
}F;

void create(Graph &G,int n ,int e)
{
    int i,j,k,w;
    char a,b;
    for(i=0;i< n;i++)
    cin>>G.data[i];
    for(i=0;i< n;i++)
    for(j=0;j< n;j++)
    {
        if(i==j)
        G.edge[i][j]=0;
        else
        G.edge[i][j]=100;
    }

    for(k=0;k< e;k++)
    {
        cin>>a;
        cin>>b;
        cin>>w;
        for(i=0;i< n;i++)
        if(G.data[i]==a) break;
        for(j=0;j< n;j++)
        if(G.data[j]==b) break;

        G.edge[i][j]=w;
        G.edge[j][i]=w;
    }
        G.n=n;
        G.e=e;
}

void Prim(Graph &G,int k)
{

}

int main()
{
    Graph my;
    int n,e;
    cin>>n>>e;
    create(my,n,e);
    Prim(my,0);
    return 0;
}

输入
第一行为图的顶点个数n第二行为图的边的条数e接着e行为依附于一条边的两个顶点和边上的权值

输出
最小生成树中的边。

样例输入

6
10
ABCDEF
A B 6
A C 1
A D 5
B C 5
C D 5
B E 3
E C 6
C F 4
F D 2
E F 6

样例输出

 (A,C)(C,F)(F,D)(C,B)(B,E)

题目有点难,参考教材284页,建议反复看几遍B站李春葆数据结构课程中prime算法一节

#include<iostream>
using namespace std;
const int maxn=100;
const int INF=101;
typedef struct
{
    int n;
    int e;
    char data[500];
    int edge[500][500];
}Graph;

typedef struct
{
    int index;
    int cost;
}mincost;

typedef struct
{
    int x;
    int y;
    int weight;
}EDGE;


typedef struct
{
    int index;
    int flag;
}F;

void create(Graph &G,int n ,int e)
{
    int i,j,k,w;
    char a,b;
    for(i=0;i< n;i++)
    cin>>G.data[i];
    for(i=0;i< n;i++)
    for(j=0;j< n;j++)
    {
        if(i==j)
        G.edge[i][j]=0;
        else
        G.edge[i][j]=100;
    }

    for(k=0;k< e;k++)
    {
        cin>>a;
        cin>>b;
        cin>>w;
        for(i=0;i< n;i++)
        if(G.data[i]==a) break;
        for(j=0;j< n;j++)
        if(G.data[j]==b) break;

        G.edge[i][j]=w;
        G.edge[j][i]=w;
    }
        G.n=n;
        G.e=e;
}
//参考教材284页
void Prim(Graph &G,int v)
{
    int lowcost[maxn];
    int MIN;
    int closest[maxn],i,j,k;
    //closest[i] 表示V-U集合中i点到U的最小边
    //类似学生与学校的距离,学生是点,学校是一个区域
    //如closest[j]=v 表示j到与集合U中的v点相连
    //形成的距离是最短距离,距离是lowcost[j]
    for(i=0;i<G.n;i++)
    //初始时U集合中只有v一个结点
    //V-U集合中各点到U集合的边权,都是 起点v到i 的距离
    //即V-U集合中各点只与集合U中的v相连
    {
        lowcost[i]=G.edge[v][i];
        closest[i]=v;
    }
    for(i=1;i<G.n;i++)
    {
        MIN=INF;
        for(j=0;j<G.n;j++)
        {
            if(lowcost[j]!=0&&lowcost[j]<MIN)
            //找最短距离,lowcost[j]表示集合U-V中的顶点j到集合U的最短距离
            //如果lowcost[j]==0,则表示j在集合U中
            {
                MIN=lowcost[j];
                k=j;
            }
        }
        printf("(%c,%c)",G.data[closest[k]],G.data[k]);
        lowcost[k]=0;//表示k点已移动到集合U中
        for(j=0;j<G.n;j++)
        //以集合U中新加入点k为中介点
        //更新集合U-V中各点到k的距离(集合U-V中各点到集合U的距离)
        //若有更短距离,则更新
        {
            if(lowcost[j]!=0&&G.edge[k][j]<lowcost[j])
            //①若j不在集合U中
            //②k到集合U-V中j点的距离小于j点到集合U的距离
            //则更新数据
            {
                lowcost[j]=G.edge[k][j];
                closest[j]=k;
            }
        }
    }
}

int main()
{
    Graph my;
    int n,e;
    cin>>n>>e;
    create(my,n,e);
    Prim(my,0);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值