【PTA】【数据结构与算法】最小生成树

判断题

1.Let M be the minimum spanning tree of a weighted graph G. Then the path in M between V1 and V2 must be the shortest path between them in G.
TF
2.Prim’s algorithm is to maintain a forest and to merge two trees into one at each stage.
TF
3.Kruskal’s algorithm is to maintain a forest and to merge two trees into one at each stage.
TF
4.Kruskal’s algorithm is to grow the minimum spanning tree by adding one edge, and thus an associated vertex, to the tree in each stage.
TF
5.Prim’s algorithm is to grow the minimum spanning tree by adding one edge, and thus an associated vertex, to the tree in each stage.
TF
6.If graph G is a connected graph, the spanning tree of G is a maximal connected subgraph containing all n vertices of G.
TF

选择题

1.给定有权无向图的邻接矩阵如下,其最小生成树的总权重是:

在这里插入图片描述

选项
A8
B15
C20
D22
2.给定有权无向图的邻接矩阵如下,其最小生成树的总权重是:

在这里插入图片描述

选项
A24
B 23
C18
D17
3.给定有权无向图如下。关于其最小生成树,下列哪句是对的?

在这里插入图片描述

选项
A边(B, A)一定在树中,树的总权重为23
B边(D, C)一定在树中,树的总权重为20
C最小生成树不唯一,其总权重为23
D最小生成树唯一,其总权重为20
4.任何一个无向连通图的最小生成树()。
选项
A一定有多棵
B可能不存在
C有一棵或多棵
D只有一棵
5.无向连通图的最小生成树( )
选项
A一定唯一
B 有一个或多个
C一定有多个
D可能不存在
6.对于下列的网,使用Prim算法由顶点A出发,求最小生成树,吸取的第三条边是。

在这里插入图片描述

选项
A(A,D)
B(D,E)
C(C,E)
D(B,C)
7.下列说法中正确的是
选项
A若一个无向图的最小生成树唯一,则该无向图中没有权值相同的边
B若一个无向完全图有 N 个顶点,且各边权值均相同,则该图有 N! 种最小生成树
C若一个无向连通图没有权值相同的边,则该无向图的最小生成树唯一
D一个无向图的最小生成树是该图的极大连通子图
8.在求最小生成树时,Prim算法更适合于____。
选项
A有向图
B无向图
C稀疏图
D稠密图
9.在求最小生成树时,Kruskal算法更适合于____。
选项
A有向图
B无向图
C稀疏图
D稠密图
10.以下哪个不是给定无向带权图的最小生成树?

在这里插入图片描述

选项
A—
B—
C—
D—
11.给出如下图所示的具有 7 个结点的网 G,采用Prim算法,从4号结点开始,给出该网的最小生成树。下列哪个选项给出了正确的树结点收集顺序?

6-10.JPG

选项
A4501362
B4526301
C4561023
D4563201
12.The minimum spanning tree of any connected weighted graph:
选项
Ais unique
Bis not unique
Cmay not be unique
Dmay not exist

程序填空题

1.最小生成树(普里姆算法)。
#include <iostream>
#define MVNum 100
#define MaxInt 32767 
using namespace std;

struct edge{
	char adjvex;
	int lowcost;
}closedge[MVNum];

typedef struct{ 
	char vexs[MVNum];   
	int arcs[MVNum][MVNum]; 
	int vexnum,arcnum;
}AMGraph;

int LocateVex(AMGraph G , char v);//实现细节隐藏
int CreateUDN(AMGraph &G);//实现细节隐藏

int Min(AMGraph G){
	int i;
	int index = -1;
	int min = MaxInt;
	for(i = 0 ; i < G.vexnum ; ++i){
		if(min > closedge[i].lowcost && closedge[i].lowcost != 0){
			min = closedge[i].lowcost;
			index = i;
		}
	}
	return index;
}

void MiniSpanTree_Prim(AMGraph G, char u){ 
	int k , j , i;
	char u0 , v0;
    k =LocateVex(G, u);
    for(j = 0; j < G.vexnum; ++j){ 
		if(j != k){  
			closedge[j].adjvex = u;
			closedge[j].lowcost = G.arcs[k][j];
		}
	}
	closedge[k].lowcost = 0;
	for(i = 1; i < G.vexnum; ++i){
		k = Min(G);  
		u0 = closedge[k].adjvex;
		v0 = G.vexs[k]; 
		cout << u0 << "->" << v0 << endl;
		closedge[k].lowcost = 0; 
		for(j = 0; j < G.vexnum; ++j) 
			if(G.arcs[k][j] < closedge[j].lowcost){
				closedge[j].adjvex = G.vexs[k];
				closedge[j].lowcost = G.arcs[k][j];
			}
	}
}

int main(){
	AMGraph G;
	CreateUDN(G);
	char u;
	cin >> u;
	MiniSpanTree_Prim(G , u);
	return 0;
}
2.最小生成树(克鲁斯卡尔算法)。
#include <stdio.h>
#define MVNum 100  
#define MaxInt 32767 

typedef struct{ 
	char vexs[MVNum];
	int arcs[MVNum][MVNum];
	int vexnum,arcnum; 
}AMGraph;

struct Evode{
	char Head;
	char Tail;
	int lowcost;
}Edge[(MVNum * (MVNum - 1)) / 2];

int Vexset[MVNum];

int LocateVex(AMGraph G , char v){
	for(int i = 0; i < G.vexnum; ++i)
		if(G.vexs[i] == v)
			return i;
		return -1;
}

void CreateUDN(AMGraph &G){ 
	int i , j , k;
	char c;
    scanf("%d %d",&G.vexnum,&G.arcnum);	
	getchar();
    for(i = 0; i < G.vexnum; ++i){   
		G.vexs[i]=getchar();
	}
	getchar();
    for(i = 0; i < G.vexnum; ++i)  
		for(j = 0; j < G.vexnum; ++j)   
			G.arcs[i][j] = MaxInt;
	for(k = 0; k < G.arcnum;++k){
		char v1 , v2;
		int w;
		scanf("%c %c %d",&v1,&v2,&w);
		getchar();
		i = LocateVex(G, v1);  j = LocateVex(G, v2); 
		G.arcs[i][j] = w;
		G.arcs[j][i] = G.arcs[i][j];
		Edge[k].lowcost = w;
		Edge[k].Head = v1;
		Edge[k].Tail =v2;
	}
}

void Sort(AMGraph G){
	int m = G.arcnum - 2;
	int flag = 1;
	while((m > 0) && flag == 1){
		flag = 0;
		for(int j = 0 ; j <= m ; j++){
			if(Edge[j].lowcost > Edge[j+ 1].lowcost){
				flag = 1;
				struct Evode temp=Edge[j];
				Edge[j]=Edge[j + 1];
				Edge[j + 1]=temp;
			}
		}
		--m;
	}
}

void MiniSpanTree_Kruskal(AMGraph G){ 
    int i , j , v1 , v2 , vs1 , vs2;
	Sort(G);  
	for(i = 0; i < G.vexnum; ++i) 
        Vexset[i] = i;
    for(i = 0; i < G.arcnum; ++i){      
		v1 =LocateVex(G, Edge[i].Head); 
		v2 =LocateVex(G, Edge[i].Tail); 
		vs1 = Vexset[v1];
		vs2 = Vexset[v2]; 
		if(vs1 != vs2){
			printf("%c->%c\n",Edge[i].Head ,Edge[i].Tail); 
			for(j = 0; j < G.vexnum; ++j)
				if(Vexset[j] == vs2) Vexset[j] = vs1;
		}
    }
}

int main(){
	AMGraph G;
	CreateUDN(G);
	MiniSpanTree_Kruskal(G);
	return 0;
}
3.下列代码的功能是使用Prim算法求出无向图的最小生成树权值总和,请补全。

给出的图用邻接矩阵存储。若两顶点之间没有直接路径,则对应权值为 INF,且题目保证 INF 值足够大;若找不到距离最短的顶点或者无法求出权值总和,则返回 ERROR。

typedef int WeightType;
typedef int VertexType;
typedef struct {
    int Nv;
    WeightType G[MAX_GRAPH_SIZE][MAX_GRAPH_SIZE];
} GNode, * MGraph;

VertexType FindMinDist(MGraph Graph, WeightType dist[]) {
    VertexType MinV = -1, V;
    WeightType MinDist = INF;
    for (V = 0; V < Graph->Nv; V++) {
        if (dist[V] != 0 && dist[V] < MinDist) {
            MinDist = dist[V];
            MinV = V;
        }
    }
    if (MinDist < INF) {
        return MinV;
    } else {
        return ERROR;
    }
}

int Prim(MGraph Graph) {
    int dist[MAX_GRAPH_SIZE];
    int TotalWeight = 0, VCount = 0;
    VertexType  V, W;
    for (V = 0; V < Graph->Nv; V++) {
        dist[V] = Graph->G[0][V];
    }
    dist[0] = 0;
    VCount++;
    while (1) {
        VertexType MinV;
        if ((MinV = FindMinDist(Graph, dist)) == ERROR) {
            break;
        }
        TotalWeight += dist[MinV];
        dist[MinV] = 0;
        VCount++;
        for (W = 0; W < Graph->Nv; W++) {
            if (dist[W] != 0 && dist[W] > Graph->G[MinV][W]) {
                dist[W] = Graph->G[MinV][W];
            }
        }
    }
    if (VCount != Graph->Nv) {
        return ERROR;
    } else {
        return TotalWeight;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值