B.Kruskal算法:(贪心)按权值递增顺序删去图中的边,若不形成回路则将此边加入最小生成树。function find(v:integer):integer; {返回顶点v所在的集合}var i:integer;

题目

B.Kruskal算法:(贪心)

按权值递增顺序删去图中的边,若不形成回路则将此边加入最小生成树。

function find(v:integer):integer; {返回顶点v所在的集合}

var i:integer;


相似考题

4.阅读下列C程序和程序说明,将应填入(n)处的字句写在答题纸的对应栏内。【说明】用克鲁斯卡尔算法求解给定图的最小生成树。include <stdio. h>include <stdlib. h>define MAXN 30typedef struct{ int v1,v2; /*一条边依附的两个顶点*/int weight; /*边上的权值*/}EDGE;typedef struct{ int Vnum; /*图中的顶点数目*/EDGE e[MAXN*(MAXN-1)/2]; /*图中的边*/}Graph;typedef struct node{ /*用链表存储同一个连通分量的顶点*/int v;struct node *next;}Alist;void heapadjust(EDGE data[], int s, int m){ /*将元素序列data[s..m]调整为小顶堆, 堆顶元素(最小元素)为data[s]*/int j;EDGE t;t=data[s]; /*备份元素data[s], 为其找到适当位置后再插入*/for(j=2*s+1; j<=m; j=j*2+1){/*沿值较小的子结点向下筛选*/if(j<m &&(1)) ++j;if(!(t. weight>data[j]. weight)) break;data[s]=data[j];s=j; /*用s记录待插入元素的位置(下标)*/}/*for*/data[s]=t; /*将备份元素插入由s所指出的插入位置*/}/*heapadjust*/int creat_graph(Graph *p) /*输入图中的顶点及边, 返回图中边的数目*/{ int k=0; /*记录图中边的数目*/int n;int v1,v2;int w;printf("vertex number of the graph:");scanf("%d", &n); /*输入图中的顶点数目*/if(n<1) return 0;p->Vnum=n;do{ printf("edge(vertex1,vertex2,weight):");scanf("%d %d %d", &V1, &v2, &w);if(v1>=0 && v1<n && v2>=0 && v2<n){p->e[k]. v1=v1; p->e[k]. v2=v2; p->e[k]. weight=w;k++;}/*if*/}while(!( (2) ));return k; /*返回图中边的数目*/}/*creat_graph*/int kruskal(Graph G, int enumber, int tree[][3]){ /*用kruskal算法求无向连通图G的最小生成树, 图中边所得数目为enumber, *//*数组tree[][3]中存放生成树中边的顶点和边上的权值, 函数返回生成树的代价*/int i, k, m, c=0;int v1, v2;Alist *p, *q, *a[MAXN];for(i=0; i<G.Vnum; ++i){ /*将每个连通分量中的顶点存放在一个单链表中*/a[i]=(Alist*)malloc(sizeof(Alist));if(!a[i]) {printf("\n mernory allocation error!");exit(0);}/*if*/a[i]->v=i; a[i]->next=NULL;}/*for*/for(i=enumber-1; i>=0; --i)/*按照边上的权值建立小顶堆*/heapadjust( (3) );k=G. Vnum; /*k用于计算图中的连通分量数目*/m=enumber-1;i=0;do{v1=G. e[0]. v1; v2=G. e[0]. v2;p=a[v1];while(p && p->v!=v2){ /*判断当前选择的边的顶点是否在一个连通分量中*/q=p; p=p->next;}if(!p){ /*当前边的顶点不在一个连通分量中*/p=q;p->next=a[G. e[0]. v2];&nb

参考答案和解析
正确答案:

 

B.Kruskal算法:(贪心)

按权值递增顺序删去图中的边,若不形成回路则将此边加入最小生成树。
function find(v:integer):integer; {返回顶点v所在的集合}
var i:integer;

更多“B.Kruskal算法:(贪心)按权值递增顺序删去图中的边,若不形成回路则将此边加入最小生成树。function find(v:integer):integer; {返回顶点v所在的集合}var i:integer;”相关问题
  • 第1题:

    数组A在子过程或函数中定义为形参,正确的语句是( )。

    A、Private Sub sele(ByVal A( ) As integer)

    B、Private Function sale(A() As Integer) As String

    C、Private Sub sale(A() As Integer) As Integer

    D、Private Sub sale(A(i) As Integer)


    参考答案:C

  • 第2题:

    有如下程序: Private Sub Command1_Click() Dim k As Integer,m As Integer Dim p As Integer k=4:m=1 p=PC(k,m):Print p; p=PC(k,m):Print p End Sub Private Function PC(a As Integer,b As Integer) Static m As Integer,i As Integer m=0:i=2 i=i + m + 1 m=i + a + b PC=m End Function 程序运行后,输出的结果为

    A.4 6

    B.6 6

    C.8 8

    D.10 12


    正确答案:C
    解析:在Sub过程中,程序段先定义了3个Integer型变量k,m,P,并给k赋给初值4,m的初值为1,然后调用事件过程PC,并将它的值赋给p;在事件过程PC中定义了两个形参,参数的传送是通过引用实参,即将k,m的地址作为a,b的地址;在PC中,将m,I定义为静态变量,所以第一次调用后的值仍然保留,但是m,I分别都有赋值语句,将它们的值变为0,2,所以返回值不变。

  • 第3题:

    单击命令按钮时,下列程序代码的执行结果为 ( ) Function FirProc(x As Integer, y As Integer, z As Integer) FirProc=2*x+y+3*z End Function Function SecProc(x As Integer, y As Integer, z As Integer) SecProc=FirProc(z, x, y)+x End Function Private Sub Commandl Click() Dim a As Integer, b As Integer, c As Integer a=2 :b=3 :c=4 Print SecProc(c, b,A)End Sub

    A.21

    B.19

    C.17

    D.34


    正确答案:A
    解析:执行语句Print SecProc (c,b,a)时,调用SecProc函数,此时将实参c, b,a的值对应传递给形参x,y,z。得SecProc =FirProc(a,c,b)+c,此时又需要调用Fir- Proc函数将a,c,b的值传递给对应形参x,y, z。在FirProc函数中执行语句FirProc=2*x +y+3*z即执行语句FirProe=2*a+c+3 *b其结果值为2*2+4+3*3即17。故 FirProe(a,c,b)的返回值为17。再与c相加即得SecProc函数的返回值结果21。选项A正确。

  • 第4题:

    阅读下列C程序和程序说明,将应填入(n)处的字句写在对应栏内。

    【说明】 应用Prim算法求解连通网络的最小生成树问题。请阅读程序后填空。

    const int MaxInt=INT MAX; //INT MAX的值在<limits.h>中

    const int n=6; //图的顶点数,应由用户定义

    typedef int AdjMatrix[n][n]; //用二维数组作为邻接矩阵表示

    typedef struct{ //生成树的边结点

    int fromVex,to Vex; //边的起点与终点

    int weight; //边上的权值

    }TreeEdSenode;

    typedef TreeEdgeNode MST[n-1]; //最小生成树定义

    void PrimMST (AdjMatrix G,MST T,int rt){

    //从顶点rt出发构造图G的最小生成树T,rt成为树的根结点

    TreeEdgeNode e; int i,k=0,min,minpos,v;

    for(i=0;i<n;i++) //初始化最小生成树T

    if(i!=rt){

    T[k].fromVex=rt;

    (1);

    T[k++].weight=G[rt][i];

    }

    for(k=0;k<n-1;k++){ //依次求MST的候选边

    (2);

    for(i=k;i<n-1;i++) 八遍历当前候选边集合

    if(T[i].weight<min) //选具有最小权值的候选边

    {min=T[i].weight;(3);}

    if(min==MaxInt) //图不连通,出错处理

    {cerr<<“Graph is disconnected!”<<endl; exit(1);}

    e=T[minpos];T[minpos]=T[k];(4);

    v=T[k].to Vex;

    for(i=k+1;i<n-1;i++) //修改候选边集合

    if(G[v][T[i].to Vex]<T[i].weight){

    T[i].weight=G[v][T[i].toVex];

    (5);

    }

    }

    }


    正确答案:(1)T[k].toVex=I (2)min=MaxInt (3)minpos=i (4)T[k]=e; (5)T[i].fromVex=v
    (1)T[k].toVex=I (2)min=MaxInt (3)minpos=i (4)T[k]=e; (5)T[i].fromVex=v 解析:(1)T[k].toVex=i
    树n边的入度点。
    (2)min=MaxInt
    最小值变量初始化。
    (3)minpos=i
    最小值结点的位置。
    (4)T[k]=e;
    T[minpos]与T[k]交换。
    (5)T[i].fromVex=v
    候选边的出度点。

  • 第5题:

    求两数的最小公倍数

    function lcm(a,b:integer):integer;


    正确答案:

     

    begin
    if a<b then swap(a,b);
    lcm:=a;
    while lcm mod b>0 do inc(lcm,a);
    end;

  • 第6题:

    最小生成树

    A.Prim算法:

    procedure prim(v0:integer);

    var

    lowcost,closest:array[1..maxn] of integer;

    i,j,k,min:integer;


    正确答案:

     

    begin
    for i:=1 to n do begin
    lowcost[i]:=cost[v0,i];
    closest[i]:=v0;
    end;
    for i:=1 to n-1 do begin
    {寻找离生成树最近的未加入顶点k}
    min:=maxlongint;
    for j:=1 to n do
    if (lowcost[j]<min) and (lowcost[j]<>0) then begin
    min:=lowcost[j];
    k:=j;
    end;
    lowcost[k]:=0; {将顶点k加入生成树}
    {生成树中增加一条新的边k到closest[k]}
    {修正各点的lowcost和closest值}
    for j:=1 to n do
    if cost[k,j]<lwocost[j] then begin
    lowcost[j]:=cost[k,j];
    closest[j]:=k;
    end;
    end;
    end;{prim}

  • 第7题:

    四、排序算法

    A.快速排序:

    procedure qsort(l,r:integer);

    var i,j,mid:integer;


    正确答案:

     

    begin
    i:=l;j:=r; mid:=a[(l+r) div 2]; {将当前序列在中间位置的数定义为中间数}
    repeat
    while a[i]<mid do inc(i); {在左半部分寻找比中间数大的数}
    while a[j]>mid do dec(j);{在右半部分寻找比中间数小的数}
    if i<=j then begin {若找到一组与排序目标不一致的数对则交换它们}
    swap(a[i],a[j]);
    inc(i);dec(j); {继续找}
    end;
    until i>j;
    if l<j then qsort(l,j); {若未到两个数的边界,则递归搜索左右区间}
    if i<r then qsort(i,r);
    end;{sort}

  • 第8题:

    链表的定位函数

    loc(I:integer):pointer; {寻找链表中的第I个结点的指针}

    procedure loc(L:linklist; I:integer):pointer;

    var p:pointer;

    j:integer;


    正确答案:

     

    begin
    p:=L.head; j:=0;
    if (I>=1) and (I<=L.len) then
    while j<I do begin p:=p^.next; inc(j); end;
    loc:=p;
    end;

  • 第9题:

    有以下函数过程: Function Gys(ByVal x As Integer,ByVal y As Integer)As Integer Do While y< >0 Remender=x Mod v x=y Y=Reminder Loop Gys=x End Function 以下是调用该函数的事件过程,该程序的运行结果是 Private Sub Command1_Click( ) Dim a As Integer Dim b As Integer a=50 b=10 x=Cys(a,B)Print x End sub

    A.0

    B.10

    C.50

    D.100


    正确答案:B
    解析:首先要读懂Gys函数过程的意思,Gys函数过程返回参数y的值,具体过程是先令参数x的值为y的值,y的值为xMody的值,再令Gys值为x的值,据此本题的正确结果为10。

  • 第10题:

    Prim算法和Kruscal算法都是无向连通网的最小生成树的算法,Prim算法从一 个顶点开始,每次从剩余的顶点加入一个顶点,该顶点与当前生成树中的顶占的连边权重 最小,直到得到最小生成树开始,Kruscal算法从权重最小的边开始,每次从不在当前的生成树顶点之间的边中选择权重最小的边加入,直到得到一颗最小生成树,这两个算法都采用了( )设计策略,且( )。

    A.分治 B.贪心 C.动态规划 D.回溯 A.若网较稠密,则Prim算法更好 B.两个算法得到的最小生成树是一样的 C.Prim算法比Kruscal算法效率更高 D.Kruscal算法比Prim算法效率更高


    正确答案:B,A

  • 第11题:

    Prim算法和Kruscal算法都是无向连通网的最小生成树的算法,Prim算法从一个顶点开始,每次从剩余的顶点中加入一个顶点,该顶点与当前的生成树中的顶点的连边权重最小,直到得到一颗最小生成树;Kruscal算法从权重最小的边开始,每次从不在当前的生成树顶点中选择权重最小的边加入,直到得到一颗最小生成树,这两个算法都采用了(64)设计策略,且(65)。

    A.若网较稠密,则Prim算法更好
    B.两个算法得到的最小生成树是一样的
    C.Prim算法比Kruscal算法效率更高
    D.Kruscal算法比Prim算法效率更高

    答案:A
    解析:
    Prim算法和Kruscal算法都是基于贪心算法的应用。Prim算法的时间复杂度为O(n2),与图中边数无关,该算法适合于稠密图。Kruskal算法的时间复杂度只和边有关系,为O(elog2e),由于Kruskal算法只与边有关,因此适合求稀疏图的最小生成树。

  • 第12题:

    Prim算法和Kruscal算法都是无向连通网的最小生成树的算法,Prim算法从一个顶点开始,每次从剩余的顶点中加入一个顶点,该顶点与当前的生成树中的顶点的连边权重最小,直到得到一颗最小生成树;Kruscal算法从权重最小的边开始,每次从不在当前的生成树顶点中选择权重最小的边加入,直到得到一颗最小生成树,这两个算法都采用了(64)设计策略,且(65)。

    A.分治
    B.贪心
    C.动态规划
    D.回溯

    答案:B
    解析:
    Prim算法和Kruscal算法都是基于贪心算法的应用。Prim算法的时间复杂度为O(n2),与图中边数无关,该算法适合于稠密图。Kruskal算法的时间复杂度只和边有关系,为O(elog2e),由于Kruskal算法只与边有关,因此适合求稀疏图的最小生成树。

  • 第13题:

    如果Add函数的调用代码为:func main() {var a Integer = 1var b Integer = 2var i interface{} = asum := i.(Integer).Add(b)fmt.Println(sum)}则Add函数定义正确的是()

    A.type Integer intfunc (a Integer) Add(b Integer) Integer { return a + b}

    B.type Integer intfunc (a Integer) Add(b *Integer) Integer { return a + *b}

    C.type Integer intfunc (a *Integer) Add(b Integer) Integer { return *a + b}

    D.type Integer intfunc (a *Integer) Add(b *Integer) Integer { return *a + *b}


    参考答案:A

  • 第14题:

    阅读下列函数说明和C代码,将应填入(n)处的字句写上。

    [说明]

    若要在N个城市之间建立通信网络,只需要N-1条线路即可。如何以最低的经济代价建设这个网络,是一个网的最小生成树的问题。现要在8个城市间建立通信网络,其问拓扑结构如图5-1所示,边表示城市间通信线路,边上标示的是建立该线路的代价。

    [图5-1]

    无向图用邻接矩阵存储,元素的值为对应的权值。考虑到邻接矩阵是对称的且对角线上元素均为0,故压缩存储,只存储上三角元素(不包括对角线)。

    现用Prim算法生成网络的最小生成树。由网络G=(V,E)构造最小生成树T=(U,TE)的Prim算法的基本思想是:首先从集合V中任取一顶点放入集合U中,然后把所有一个顶点在集合U里、另一个顶点在集合V-U里的边中,找出权值最小的边(u,v),将边加入TE,并将顶点v加入集合U,重复上述操作直到U=V为止。

    函数中使用的预定义符号如下:

    define MAX 32768 /*无穷大权,表示顶点间不连通*/

    define MAXVEX 30 /*图中顶点数目的最大值*/

    typedef struct{

    int startVex,stopVex; /*边的起点和终点*/

    float weight; /*边的权*/

    }Edge;

    typedef struct{

    char vexs[MAXVEX]; /*顶点信息*/

    float arcs[MAXVEX*(MAXVEX-1)/2]; /*邻接矩阵信息,压缩存储*/

    int n; /*图的顶点个数*/

    }Graph;

    [函数]

    void PrimMST(Graph*pGraph, Edge mst[])

    {

    int i,j,k,min,vx,vy;

    float weight,minWeight;

    Edge edge;

    for(i=0; i<pGraph->n-1;i++){

    mst[i].StartVex=0;

    mst[i].StopVex=i+1;

    mst[i].weight=pGraph->arcs[i];

    }

    for(i=0;i<(1);i++){/*共n-1条边*/

    minWeight=(float)MAX;

    min=i;

    /*从所有边(vx,vy)中选出最短的边*/

    for(j=i; j<pGraph->n-1; j++){

    if(mst[j].weight<minWeight){

    minWeight=(2);

    min=j;

    }

    }

    /*mst[minl是最短的边(vx,vy),将mst[min]加入最小生成树*/

    edge=mst[min];

    mst[min]=mst[i];

    mst[i]=edge;

    vx=(3);/*vx为刚加入最小生成树的顶点下标*/

    /*调整mst[i+1]到mst[n-1]*/

    for(j=i+1;j<pGraph->n-1;j++){

    vy=mst[j].StopVex;

    if( (4) ){/*计算(vx,vy)对应的边在压缩矩阵中的下标*/

    k=pGraph->n*vy-vy*(vy+1)/2+vx-vy-1;

    }else{

    k=pGraph->n*vx-vx*(vx+1)/2+vy-vx-1;

    }

    weight(5);

    if(weight<mst[j].weight){

    mst[j].weight=weight;

    mst[j].StartVex=vx;

    }

    }

    }

    }

    (1)


    正确答案:pGraph->n-1
    pGraph->n-1

  • 第15题:

    有如下程序: Private Sub Command1_Click() Dim k As Integer,m As Integer Dim op As Integer k=4:m=1 p=PPC(k,m):Print op; p=PPC(k.m):Print op End Sub Private Function PPC(a As Integer,b As Integer) Static m As Integer,i As Integer m=0:i=2 i=i+m+1 m=i+a+b PPC=m End Function 程序运行后,输出的结果为

    A.4 6

    B.6 6

    C.8 8

    D.10 12


    正确答案:C
    解析:考查考生对函数及函数参数的运用。
      [解题要点] 在Sub过程中,程序段先定义了3个Integer型变量k,m,op,并为k赋给初值4,m的初值为1,然后调用事件过程PPC,并将它的值赋给op。在事件过程PPC中定义了两个形参,参数的传送通过引用实参,即将k,m的地址作为a,b的地址;在PPC中,将m,i定义为静态变量,第一次调用后的值仍然保留,但是m,i分别都有赋值语句,将它们的值变为0,2,所以返回值不变。
      [错解分析] 函数PPC中的两个参数都是以传值方式传递,注意不要与传地址方式传递混淆。
      [考点链接] 过程的定义和调用,以及参数传递方式的选择。

  • 第16题:

    以下用户自定义函数 Function Func(a As Integer, b As Integer) As Integer Static m As Integer, i As Integer m=0:i=2 i=i+m+i m=i+a+b Func=m End Function 在窗体上画一个命令按钮,然后编写如下事件过程: Private Sub Command1_Click() Dim k As Integer,m As Integer,p As Integer k=4:m=1 P=Func(k,m) Print p End Sub 程序运行后,单击命令按钮,输出结果为

    A.8

    B.9

    C.10

    D.11


    正确答案:A
    解析:变量i的计算过程为i=2+0+1=3,变量m的计算过程为m=3+4+1=8,m的值通过于函数名Fune返回。

  • 第17题:

    素数的求法

    A.小范围内判断一个数是否为质数:

    function prime (n: integer): Boolean;

    var I: integer;


    正确答案:

     

    begin
    for I:=2 to trunc(sqrt(n)) do
    if n mod I=0 then begin
    prime:=false; exit;
    end;
    prime:=true;
    end;

  • 第18题:

    C. Dijkstra 算法:

    var

    a:array[1..maxn,1..maxn] of integer;

    b,pre:array[1..maxn] of integer; {pre[i]指最短路径上I的前驱结点}

    mark:array[1..maxn] of boolean;

    procedure dijkstra(v0:integer);


    正确答案:

     

    begin
    fillchar(mark,sizeof(mark),false);
    for i:=1 to n do begin
    d[i]:=a[v0,i];
    if d[i]<>0 then pre[i]:=v0 else pre[i]:=0;
    end;
    mark[v0]:=true;
    repeat {每循环一次加入一个离1集合最近的结点并调整其他结点的参数}
    min:=maxint; u:=0; {u记录离1集合最近的结点}
    for i:=1 to n do
    if (not mark[i]) and (d[i]<min) then begin
    u:=i; min:=d[i];
    end;
    if u<>0 then begin
    mark[u]:=true;
    for i:=1 to n do
    if (not mark[i]) and (a[u,i]+d[u]<d[i]) then begin
    d[i]:=a[u,i]+d[u];
    pre[i]:=u;
    end;
    end;
    until u=0;
    end;

  • 第19题:

    折半查找

    function binsearch(k:keytype):integer;

    var low,hig,mid:integer;


    正确答案:

     

    begin
    low:=1;hig:=n;
    mid:=(low+hig) div 2;
    while (a[mid].key<>k) and (low<=hig) do begin
    if a[mid].key>k then hig:=mid-1
    else low:=mid+1;
    mid:=(low+hig) div 2;
    end;
    if low>hig then mid:=0;
    binsearch:=mid;
    end;

  • 第20题:

    有如下函数: Function fun(a As Integer,n As Integer)As Integer Dim m AS Integer While a>=n a=a-n:m=m+1 Wend Fun=m End Function 该函数的返回值是。 A.a乘以n的乘积 B.a加n的和 C.a减n的差 D.a除以n的商(不含小数部分)


    正确答案:D

  • 第21题:

    在窗体上画一个按钮,然后编写如下的事件代码。在按钮上单击,输出为( )。 Private Function fun(x As Integer,y As Integer) Static m As Integer Static i As Integer i=i+2 i=i+m+1 m=i+x+y fun=m End Function Private Sub Command1_Click() Dim j As Integer,m As Integer,k As Integer j=4:m=1 k=fun(j,m) Print k; k=fun (j,m) Print k End Sub

    A.8 18

    B.7 17

    C.7 19

    D.8 19


    正确答案:D
    解析:当发生Command1的单击事件时,定义了两个变量j和m,并依次赋值为4和1,然后调用fun函数,把i和m按地址传递给x和y,进入fun函数执行。在fun函数中定义了两个静态变量m和i,执行三条赋值语句后i的值为3,m的值为8,通过给函数名赋值把8作为函数值返回并赋值给k,输出k的值为8;再一次调用函数fun,把j和m依次按地址传给x和y,进入fun函数执行,注意,由于m和i是静态变量,此时的值不再是0,而是上一次退出时的值为3和8。执行三条赋值语句后i的值为14,m的值为19,通过给函数名赋值,把19作为函数值返回并赋值给k,输出k的值为19。

  • 第22题:

    ●试题四

    阅读下列算法说明和算法,将应填入(n)的字句写在答题纸的对应栏内。

    【说明】

    下列最短路径算法的具体流程如下:首先构造一个只含n个顶点的森林,然后依权值从小到大从连通网中选择不使森林中产生回路的边加入到森林中去,直至该森林变成一棵树为止,这棵树便是连通网的最小生成树。该算法的基本思想是:为使生成树上总的权值之和达到最小,则应使每一条边上的权值尽可能地小,自然应从权值最小的边选起,直至选出n-1条互不构成回路的权值最小边为止。

    图5算法流程图

    【算法】

    /*对图定义一种新的表示方法,以一维数组存放图中所有边,并在构建图的存储结构时将它构造为一个"有序表"。以顺序表MSTree返回生成树上各条边。*/

    typedef struct{

    VertexType vex1;

    VertexType vex2;

    VRType weight;

    }EdgeType;

    typedef ElemType EdgeType;

    typedef struct{//有向网的定义

    VertexType vexs[MAX_VERTEX_NUM];//顶点信息

    EdgeType edge[MAX_EDGE_NUM];//边的信息

    int vexnum,arcnum;//图中顶点的数目和边的数目

    }ELGraph;

    void MiniSpanTree_Kruskal(ELGraph G,SqList& MSTree){

    //G.edge 中依权值从小到大存放有向网中各边

    //生成树的边存放在顺序表MSTree中

    MFSetF;

    InitSet(F,G.vexnum);//将森林F初始化为n棵树的集合

    InitList(MSTree,G.vexnum);//初始化生成树为空树

    i=0;k=1;

    while(k< (1) ){

    e=G.edge[i];//取第i条权值最小的边

    /*函数fix_mfset返回边的顶点所在树的树根代号,如果边的两个顶点所在树的树根相同,则说明它们已落在同一棵树上。*/

    rl=fix_mfset(F,LocateVex(e.vex1));

    r2= (2) //返回两个顶点所在树的树根

    if(r1 (3) r2){//选定生成树上第k条边

    if(ListInsert(MSTree,k,e){ (4) ;//插入生成树

    mix_mfset(E,rl,r2);//将两棵树归并为一棵树

    }

    (5) ;//继续考察下一条权值最小边

    }

    DestroySet(F);

    }


    正确答案:
    ●试题四【答案】(1)G.vexnum(2)fix_mfset(F,LocateVex(e.vex2))(3)!=(4)k++(5)i++【解析】本题考查的是克鲁斯卡尔(Kruskal)算法。理解该算法的关键在于:由于生成树上不允许有回路,因此并非每一条居当前权值最小的边都可选。例如,如图2所示的连通网G5,在依次选中了(e,f),(b,c),(e,d)和(f,g)的4条边之后,权值最小边为(g,d),由于g和d已经连通,若加上(g,d)这条边将使生成树上产生回路,显然这条边不可取。同理,边(f,d)也不可取,之后则依次取(a,g)和(a,b)两条边加入到生成树。那么在算法中如何判别当前权值最小边的两个顶点之间是否已经连通?从生成树的构造过程可见,初始态为n个顶点分属n棵树,互不连通,每加入一条边,就将两棵树合并为一棵树,在同一棵树上的两个顶点之间自然相连通。由此判别当前权值最小边是否可取只要判别它的两个顶点是否在同一棵树上即可。

  • 第23题:

    Prim算法和Kruscal算法都是无向连通网的最小生成树的算法,Prim算法从一个顶点开始,每次从剩余的顶点中加入一个顶点,该顶点与当前的生成树中的顶点的连边权重最小,直到得到一颗最小生成树;Kruscal算法从权重最小的边开始,每次从不在当前的生成树顶点中选择权重最小的边加入,直到得到一颗最小生成树,这两个算法都采用了(请作答此空)设计策略,且( )。

    A.分治
    B.贪心
    C.动态规划
    D.回溯

    答案:B
    解析:
    Prim算法和Kruscal算法都是基于贪心算法的应用。Prim算法的时间复杂度为O(n2),与图中边数无关,该算法适合于稠密图。Kruskal算法的时间复杂度只和边有关系,为O(elog2e),由于Kruskal算法只与边有关,因此适合求稀疏图的最小生成树。