最小生成树

假如想象 提交于 2020-02-08 23:10:35

prim算法

有两个集合,第一个集合,存放最小生成树,第二个集合,用来存放还没有进入最小生成树的结点。但这两个集合实际上是用同一个数组表示的。
我们用closedge[100]来表示这个数组,每个单元由“string Data;”和“int lowcost;”两部分组成。其中closedge[1]表示图中的第一个结点v1,closedge【1】.Data表示v1到最小生成树最短路径的结点(假设为v2),closedge【1】.lowcost就是v1到v2的距离。如果closedge【1】.lowcoat为0,就说明它已经在最小生成树中了。
prim算法的核心思想,就是以最小生成树为研究对象,每次在还没有进入最小生成树的结点中,找到路径最小的那个。假设目前的最小生成树为v2,v1是所有结点中,到它最短的一个,那么我们就把v1加入到最小生成树中,过程为:closedge【1】.lowcoat赋为0;把closedge【1】.Data赋为v1;在剩下的结点中,寻找是否有结点到v1的距离,小于此几点到v2的距离,如果有,那么此时此节点到最小生成树的距离,就是到v1的距离。总共n个结点,就重复此步骤n-1次。

#include<iostream>
#include<string.h>
using namespace std;
typedef struct Graph
{
    string Name[100];
    int Arr[100][100];
    int Vex_num, Edge_num;
};
struct Node
{
    string Data;
    int lowcost;
}closedge[100];
int Get_Location(Graph T,string name)
{
    for(int i = 1; i <= T.Vex_num; i++)
    {
        if(T.Name[i] == name)
            return i;
    }
    cout<<"Error!Not found!"<<endl;
    exit(1);
}
void Create_Graph(Graph &T)
{
    cin>>T.Vex_num>>T.Edge_num;
    for(int i = 1; i <= T.Vex_num; i++)
    {
        cin>>T.Name[i];
        for(int j = 1; j <= T.Vex_num; j++)
            T.Arr[i][j] = 100;
    }
    string n1, n2;int x, y, w;
    for(int i = 1; i <= T.Edge_num; i++)
    {
        cin>>n1>>n2>>w;
        x = Get_Location(T,n1);
        y = Get_Location(T,n2);
        T.Arr[x][y] = w;T.Arr[y][x] = w;
    }
}
int Get_Min(Node closedge[],int n)
{
    int Min = 100;int index;
    for(int i = 1; i <= n; i++)
    {
        if(closedge[i].lowcost < Min && closedge[i].lowcost != 0)
        {
            Min = closedge[i].lowcost;
            index = i;
        }
    }
    return index;
}
void MiniSpanTree_prim(Graph T,string name)
{
    int k = Get_Location(T,name);    //确认开始点位置
    closedge[k].lowcost = 0;        //开始点此时就是最小生成树
    for(int i = 1; i <= T.Vex_num; i++)
    {
        if(i != k)                  //剩下的所有结点到最小生成树的距离
        closedge[i] = {name,T.Arr[k][i]};
    }
    string n1, n2;
    cout<<"最小生成树"<<endl<<"从\t"<<"到"<<endl;
    for(int i = 1; i < T.Vex_num; i++)
    {
        k = Get_Min(closedge,T.Vex_num);  //到最小生成树距离的最小结点位置
        n1 = closedge[k].Data;          //与次结点相连的最小成成树中的结点
        n2 = T.Name[k];                 //此结点
        cout<<n1<<"\t"<<n2<<endl;
        closedge[k].lowcost = 0;        //此节点进入最小生成树
        for(int j = 1; j <= T.Vex_num; j++)
        {
            if(T.Arr[j][k] < closedge[j].lowcost)
                closedge[j] = {T.Name[k],T.Arr[j][k]};
        }
    }
}
int main()
{
    Graph T;
    Create_Graph(T);
    MiniSpanTree_prim(T,"v1");
}




//测试数据
/*
6 10
v1 v2 v3 v4 v5 v6
v1 v2 6
v1 v4 5
v1 v3 1
v2 v3 5
v2 v5 3
v3 v4 5
v3 v5 6
v3 v6 4
v4 v6 2
v5 v6 6

*/


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!