12-A. DS图—最小生成树

实验12-图连通与最小生成树-
题目描述
根据输入创建无向网。分别用Prim算法和Kruskal算法构建最小生成树。(假设:输入数据的最小生成树唯一。)

输入
顶点数n

n个顶点

边数m

m条边信息,格式为:顶点1顶点2权值

Prim算法的起点v

输出
输出最小生成树的权值之和

对两种算法,按树的生长顺序,输出边信息(Kruskal中边顶点按数组序号升序输出)

输入样例
6
v1 v2 v3 v4 v5 v6
10
v1 v2 6
v1 v3 1
v1 v4 5
v2 v3 5
v2 v5 3
v3 v4 5
v3 v5 6
v3 v6 4
v4 v6 2
v5 v6 6
v1

输出样例
15
prim:
v1 v3 1
v3 v6 4
v6 v4 2
v3 v2 5
v2 v5 3
kruskal:
v1 v3 1
v4 v6 2
v2 v5 3
v3 v6 4
v2 v3 5

#include 
using namespace std;

#define MAX_WEIGHT 99999

struct
{
    string adjvex;
    int weight;
} Close_Edge[100];

class MGraph
{
    int Graph_Prim[100][100], Graph_Kruskal[100][100];
    int n, nedge;
    int visited[100];
    string *node;
    string start;
    int startpos;
public:
    MGraph(){}
    void SetMGraph()
    {
        int i,j;
        cin>>n;//顶点数
        for(i=0; i<n; i++)//初始化
            for(j=0; j<n; j++)
            {
                Graph_Prim[i][j] = 10000;
                Graph_Kruskal[i][j] = 10000;
            }

        node=new string[n];//n个顶点
        for(i=0; i<n; i++)
            cin>>node[i];

        cin>>nedge;//边数
        for(i=1; i<=nedge; i++)
        {
            string ch1, ch2;
            int weight_;
            cin>>ch1>>ch2>>weight_;//顶点1;顶点2;权值
            
            int loc1,loc2;
            for(j=0;j<n;j++)
            {
                if(node[j]==ch1)
                    loc1=j;
                if(node[j]==ch2)
                    loc2=j;
            }
            
            Graph_Kruskal[loc1][loc2] = Graph_Prim[loc1][loc2] = weight_;
            Graph_Kruskal[loc1][loc2] = Graph_Prim[loc2][loc1] = weight_;
            
        }
        cin>>start;//Prim算法的起点名字
        for(i=0; i<n; i++)
            if(node[i]==start)
                startpos=i;//起点编号
    }
    
    void Prim()//Prim算法
    {
        int i,j;
        for(i=1; i<=n; i++)//初始化
            visited[i]=0;
        visited[startpos]=1;//起点已访问
        int min_;

        //找出每个点周围权值最小的边及其邻接的点
        for(i=0; i<n; i++)
        {
            min_=MAX_WEIGHT;
            for(j=0;j<n;j++)
                if(Graph_Prim[i][j]<min_)
                {
                    min_ = Graph_Prim[i][j];
                    Close_Edge[i].adjvex = node[j];
                    Close_Edge[i].weight = min_;
                }
        }

        string s3;
        string *e1,*e2;
        int *w3;
        e1=new string[100];
        e2=new string[100];
        w3=new int[100];

        int index, k=0;
        for(i=0; i<n; i++)
        {
            min_ = MAX_WEIGHT;
            for(j=0; j<n; j++)
            {
                if(!visited[j])
                    continue;
                else
                {
                    if(min_>Close_Edge[j].weight)
                    {
                        min_ = Close_Edge[j].weight;
                        s3 = Close_Edge[j].adjvex;
                        index = j;
                    }
                }
            }
            e1[k] = node[index];
            e2[k] = s3;
            w3[k++] = min_;

            for(int g=0; g<n; g++) //标记已连接的点
            {
                if(node[g]==s3)
                {
                    visited[g] = 1;
                    break;
                }
            }
            for(int g=0; g<n; g++)
            {
                min_ = MAX_WEIGHT;
                for(int m=0; m<n; m++)
                {
                    if(min_>Graph_Prim[g][m] && visited[m]==0)
                    {
                        min_ = Graph_Prim[g][m];
                        Close_Edge[g].adjvex=node[m];
                        Close_Edge[g].weight=min_;
                    }
                }
            }
        }
        int Weight=0;
        for(i=0; i<k-1; i++)
        {
            Weight+=w3[i];
        }
        cout<<Weight<<endl;
        cout<<"prim:"<<endl;
        for(i=0; i<k-1; i++)
            cout<<e1[i]<<" "<<e2[i]<<" "<<w3[i]<<endl;
    }
    
    void Kruskal()//Kruskal算法
    {
        int i,k,j;
        cout<<"kruskal:"<<endl;
        int *uni = new int[n];

        for(i=0; i<n; i++)
            uni[i] = i;

        for(i=0; i<n-1; i++)
        {
            int min=MAX_WEIGHT;
            int x, y;
            for(j=0; j<n; j++) //找出权值最小的边
                for(k=0; k<n; k++)
                {
                    if(j==k)
                        continue;
                    if(uni[j]==uni[k])
                        continue;
                    else
                    {
                        if(min>Graph_Kruskal[j][k])
                        {
                            min = Graph_Kruskal[j][k];
                            x=j; y=k;
                        }
                    }
                }
            Graph_Kruskal[x][y] = MAX_WEIGHT;
            Graph_Kruskal[y][x] = MAX_WEIGHT;

            if(x>y)
                swap(x, y);

            for(j=0;j<n;j++)
            {
                if(uni[j]==uni[y] && j!=y)
                    uni[j] = uni[x];
            }
            uni[y] = uni[x];
            cout<<node[x]<<" "<<node[y]<<" "<<min<<endl;
        }
    }
};

int main()
{
    MGraph m,M;
    m.SetMGraph();
    m.Prim();
    m.Kruskal();
    return 0;
}

你可能感兴趣的:(数据结构,图论,算法,数据结构)