在本题中,读入一个无向图的邻接矩阵(即数组表示),建立无向图并按照以上描述中的算法建立最小生成树,并输出最小生成树的代价。 Input 输入的第一行包含一个正整数n,表示图中共有n个顶点。其中n不超过50。以后的n行中每行有n个用空格隔开的整数,对于第i行的第j个整数,如果不为0,则表示第i个顶点和第j个顶点有直接连接且代价为相应的值,0表示没有直接连接。当i和j相等的时候,保证对应的整数为0。输入保证邻接矩阵为对称矩阵,即输入的图一定是无向图,且保证图中只有一个连通分量。 Output 只有一个整数,即最小生成树的总代价。请注意行尾输出换行。 Sample Input 4 0 2 4 0 2 0 3 5 4 3 0 1 0 5 1 0 Sample Output 6 上述问题用C语言和数据结构如何写代码
时间: 2024-01-22 13:19:53 浏览: 102
数据结构-c语言-带main函数-图7.2-图的存储结构-图的邻接矩阵的创建-无向图。
以下是使用 Prim 算法求解最小生成树的 C 语言代码实现:
```c
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define MAXN 50
int n; // 图中顶点数
int graph[MAXN][MAXN]; // 邻接矩阵表示的图
int visited[MAXN]; // 标记顶点是否被访问
int dist[MAXN]; // 记录每个顶点与当前生成树的距离
int parent[MAXN]; // 记录每个顶点在当前生成树中的父节点
// 找到当前距离最小的顶点
int findMin() {
int min = INT_MAX, minIndex;
for (int i = 0; i < n; i++) {
if (!visited[i] && dist[i] < min) {
min = dist[i];
minIndex = i;
}
}
return minIndex;
}
// 计算最小生成树的代价
int prim() {
int totalCost = 0;
// 初始化
for (int i = 0; i < n; i++) {
visited[i] = 0;
dist[i] = INT_MAX;
}
dist[0] = 0; // 从任意一个顶点开始都可以
parent[0] = -1; // 0 是根节点,没有父节点
// 构造最小生成树
for (int i = 0; i < n; i++) {
int u = findMin();
visited[u] = 1;
totalCost += dist[u];
for (int v = 0; v < n; v++) {
if (graph[u][v] && !visited[v] && graph[u][v] < dist[v]) {
parent[v] = u;
dist[v] = graph[u][v];
}
}
}
return totalCost;
}
int main() {
scanf("%d", &n);
// 读入邻接矩阵
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
scanf("%d", &graph[i][j]);
}
}
int cost = prim();
printf("%d\n", cost);
return 0;
}
```
在这个实现中,我们使用了一个 `visited` 数组来标记顶点是否被访问过,一个 `dist` 数组记录每个顶点与当前生成树的距离(即到当前生成树的最小距离),一个 `parent` 数组记录每个顶点在当前生成树中的父节点。在 `prim` 函数中,我们首先初始化这些数组,然后不断从未访问的顶点中找到距离最小的顶点,并将其标记为已访问。然后遍历该顶点的所有连通的未访问的顶点,如果它们到当前生成树的距离比之前记录的更短,则更新它们的 `dist` 和 `parent` 数组。最后,我们将所有顶点到当前生成树的距离之和作为最小生成树的代价。
阅读全文