• 实验六 最小代价生成树


    一、实验名称:最小代价生成树

    二、实验目的:

    1.掌握贪心算法解决问题的思想和一般过程,
    2.学会使用普里姆算法解决实际问题。

    三、实验内容

    完善下列程序,并回答问题。

     1 #include<iostream.h>
     2 #define G_NODE_NUM 6  //结点个数
     3 #define INFTY 65535
     4 template<class T>
     5 struct ENode
     6 {//带权图的边结点
     7     int adjVex;
     8     T w;
     9     ENode* nextArc;
    10 };
    11 template <class T>
    12 class Graph
    13 {
    14 public:
    15     Graph (int mSize){
    16         n = mSize;
    17         a = new ENode<T> *[mSize];
    18         for(int i = 0; i< n ;i++){
    19             a[i] = NULL;
    20         }
    21     }
    22     void Prim(int s);
    23     void putin(T X[G_NODE_NUM][G_NODE_NUM]);
    24     void putout();
    25 protected:
    26     void Prim(int k, int* nearest, T* lowcost);
    27     ENode<T>** a;
    28     int n; 
    29 };
    30 
    31 template<class T>
    32 void Graph<T>::putin(T X[G_NODE_NUM][G_NODE_NUM]){
    33     ENode<T> *e;
    34     for(int i = 0; i < n; i++){
    35         for(int j = 0; j < n; j++){
    36             if(X[i][j]>0){
    37                 e = new ENode<T>();
    38                 e->adjVex = j;
    39                 e->w = X[i][j];
    40                 e->nextArc = a[i];
    41                 a[i] = e;
    42             }
    43         }
    44     }
    45 }
    46 template<class T>
    47 void Graph<T>::putout(){
    48     ENode<T> *e;
    49     cout<<"---图输出---"<<endl;
    50     for(int i=0; i<n; i++){
    51         e = a[i];
    52         cout<<endl<<""<<i<<"个节点:";
    53         while(e!=NULL){
    54             cout<<" "<<e->adjVex<<"("<<e->w<<")";
    55             e=e->nextArc;
    56         }
    57     }
    58     cout<<endl;
    59 }
    60 
    61 template<class T>
    62 void Graph<T>::Prim(int s)
    63 { 
    64     学生书写部分
    65 };
    66 
    67 template<class T>
    68 void Graph<T>::Prim(int k, int* nearest, T* lowcost)
    69 {
    70     学生书写部分
    71 }
    72 
    73 void main(){
    74     Graph<int> *G;
    75     int data[G_NODE_NUM][G_NODE_NUM]={    {0,6,1,5,0,0},
    76                                             {6,0,5,0,3,0},
    77                                             {1,5,0,5,6,4},
    78                                             {5,0,5,0,0,2},
    79                                             {0,3,6,0,0,6},
    80                                             {0,0,4,2,6,0}};
    81     int n = G_NODE_NUM;
    82     G = new Graph<int>(n);
    83     G->putin(data);
    84     G->putout();
    85     G->Prim(0);
    86 }
    View Code

    补充后的程序:

      1 #include<iostream.h>
      2 #define G_NODE_NUM 6  //结点个数
      3 #define INFTY 65535
      4 template<class T>
      5 struct ENode
      6 {//带权图的边结点
      7     int adjVex;
      8     T w;
      9     ENode* nextArc;
     10 };
     11 template <class T>
     12 class Graph
     13 {
     14 public:
     15     Graph (int mSize){
     16         n = mSize;
     17         a = new ENode<T> *[mSize];
     18         for(int i = 0; i< n ;i++){
     19             a[i] = NULL;
     20         }
     21     }
     22     void Prim(int s);
     23     void putin(T X[G_NODE_NUM][G_NODE_NUM]);
     24     void putout();
     25 protected:
     26     void Prim(int k, int* nearest, T* lowcost);
     27     ENode<T>** a;
     28     int n; 
     29 };
     30 
     31 template<class T>
     32 void Graph<T>::putin(T X[G_NODE_NUM][G_NODE_NUM]){
     33     ENode<T> *e;
     34     for(int i = 0; i < n; i++){
     35         for(int j = 0; j < n; j++){
     36             if(X[i][j]>0){
     37                 e = new ENode<T>();
     38                 e->adjVex = j;
     39                 e->w = X[i][j];
     40                 e->nextArc = a[i];
     41                 a[i] = e;
     42             }
     43         }
     44     }
     45 }
     46 template<class T>
     47 void Graph<T>::putout(){
     48     ENode<T> *e;
     49     cout<<"---图输出---"<<endl;
     50     for(int i=0; i<n; i++){
     51         e = a[i];
     52         cout<<endl<<""<<i<<"个节点:";
     53         while(e!=NULL){
     54             cout<<" "<<e->adjVex<<"("<<e->w<<")";
     55             e=e->nextArc;
     56         }
     57     }
     58     cout<<endl;
     59 }
     60 
     61 template<class T>
     62 void Graph<T>::Prim(int s)
     63 { 
     64     //学生书写部分
     65     int *nearest=new int[n],*lowcost=new int[n];
     66     Prim(s,nearest,lowcost);
     67     for(int j=0;j<n;j++){
     68        cout<<"("<<nearest[j]<<","<<j<<","<<","<<lowcost[j]<<")"; 
     69     }
     70     cout<<endl;
     71     delete[]nearest;
     72     delete[]lowcost;
     73 };
     74 
     75 template<class T>
     76 void Graph<T>::Prim(int k, int* nearest, T* lowcost)
     77 {
     78     //学生书写部分
     79     bool*mark=new bool[n];   //创建mark数组 
     80     ENode<T>*p;
     81     if(k<0||k>n-1)    throw  OutofBounds;    
     82     
     83     for(int i=0;i<n;i++){   //初始化 
     84         nearest[i]=-1;
     85         mark[i]=false;   
     86         lowcost[i]=INFTY; //常量INFTY的值大于所有边的权值 
     87     }
     88     
     89     //源点k加入生成树 
     90     lowcost[k]=0;
     91     nearest[k]=k;
     92     mark[k]=true; 
     93     for(int i=1;i<n;i++){
     94         for(p=a[k];p;p=p-nextArc){
     95             int j=p->adjVex;
     96             if((!mark[j])&&(lowcost    [j]>p->w)){
     97                lowcost[j]=p->w;
     98                nearest[j]=k;
     99             }
    100         }
    101     }
    102     
    103     T min=INFTY;   //求下一条最小权值的边 
    104     for(int j=0;j<n;j++){
    105         if((!mark[j])&&(lowcost    [j]<min)){
    106            min=lowcost[j];
    107            k=j;
    108         }
    109     }
    110     
    111     mark[k]=true;     //将节点k加到生成树上 
    112 }
    113 
    114 int main(){
    115     Graph<int> *G;
    116     int data[G_NODE_NUM][G_NODE_NUM]={    {0,6,1,5,0,0},
    117                                             {6,0,5,0,3,0},
    118                                             {1,5,0,5,6,4},
    119                                             {5,0,5,0,0,2},
    120                                             {0,3,6,0,0,6},
    121                                             {0,0,4,2,6,0}};
    122     int n = G_NODE_NUM;
    123     G = new Graph<int>(n);
    124     G->putin(data);
    125     G->putout();
    126     G->Prim(0);
    127 }
    View Code
    程序问题
    1. 分析算法,说明算法中涉及到的变量k、nearest、lawcast、mark,分别表示的语义是什么。
    2. 画出Prim算法的流程图。
    3. 运行课本第109页图6-10的普里姆算法,生成的子树是什么? (程序自带输入部分)
    4. 在程序的适当位置,增加“cout<<"第"<<k<<"个节点加入生成树 ";”语句,输出加入节点的次序。
    5. 试着推理,或者在程序中增加输出语句,说明从第1个节点开始,每一次循环三元组<nearest[i], i, lowcost[i]>的变化。
    6. 若是8个节点的图,如下所示,设计相应的输入邻接矩阵,通过普里姆算法得出的最小生成子树是什么?

          7.(选作)若是使用克鲁斯卡尔算法,课本第109页图6-10生成的最小子图应该是什么?

          8.(选作)若是使用克鲁斯卡尔算法,(图1)生成的最小子图应该是什么?

    四、实验总结

  • 相关阅读:
    SpringCloud_组件常用注解
    SpringBoot_启动器
    SICP习题 1.5 (应用序与正则序)
    SICP习题 1.4 ( if 语句返回运算符)
    SICP习题 1.3 (求较大两个数的递归)
    SICP习题 1.2 (前缀表达式)
    SICP习题 1.1 (if cond语句)
    MySQL5.7 踩坑实录
    类找不到总结java.lang.ClassNotFoundException
    网易校招2018----题目3----字符串碎片
  • 原文地址:https://www.cnblogs.com/liuhongfeng/p/4159796.html
Copyright © 2020-2023  润新知