毕万 2024-04-20 16:33 采纳率: 76.9%
浏览 2
已结题

C语言实用数据结构与算法

img


实用数据结构与算法C语言版,‘’图‘’的内容,最优灌溉问题。要求如上图,请教一下

  • 写回答

5条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-04-20 16:33
    关注

    引自免费微信小程序:皆我百晓生

    为了实现 Prim 和 Kruskal 算法,我们首先需要定义一个结构体来表示边(包括起始节点、结束节点和费用),以及一个数组来存储这些边。然后,我们将使用两个辅助函数,一个用于检查两个节点是否在一个集合中(对于 Prim 算法),另一个用于合并两个集合(对于 Kruskal 算法)。这里是一个详细的 C 语言实现:

    #include <stdio.h>
    #include <stdlib.h>
    
    // 定义边的数据结构
    typedef struct Edge {
        int src, dest;
        int cost;
    } Edge;
    
    // 初始化并查找操作
    int find(int parent[], int i) {
        if (parent[i] == i)
            return i;
        return find(parent, parent[i]);
    }
    
    // 合并操作
    void union_op(int parent[], int rank[], int x, int y) {
        x = find(parent, x);
        y = find(parent, y);
    
        if (rank[x] > rank[y])
            parent[y] = x;
        else {
            parent[x] = y;
            if (rank[x] == rank[y])
                rank[y]++;
        }
    }
    
    // Prim 算法
    int primMST(Edge* edges, int n, int m) {
        int minimum_cost = 0;
        int parent[n + 1];
        int visited[n + 1]; // 标记已访问的节点
        int min_edge_cost; // 当前找到的最小边的成本
    
        for (int i = 1; i <= n; i++) {
            parent[i] = -1;
            visited[i] = 0;
        }
    
        visited[1] = 1; // 假设第1个节点是根节点
    
        for (int count = 0; count < n - 1; count++) {
            min_edge_cost = INT_MAX;
            int u = -1;
    
            for (int i = 0; i < m; i++) {
                int v = edges[i].dest;
                if ((visited[v] == 0) && (edges[i].cost < min_edge_cost)) {
                    min_edge_cost = edges[i].cost;
                    u = edges[i].src;
                }
            }
    
            visited[u] = 1;
            minimum_cost += min_edge_cost;
            for (int j = 0; j < m; j++) {
                int v = edges[j].dest;
                if ((visited[v] == 0) && (edges[j].src == u))
                    parent[v] = u;
            }
        }
    
        return minimum_cost;
    }
    
    // Kruskal 算法
    int kruskalMST(Edge* edges, int n, int m) {
        int minimum_cost = 0;
        int parent[n + 1];
        int rank[n + 1];
    
        for (int i = 1; i <= n; i++) {
            parent[i] = i;
            rank[i] = 0;
        }
    
        Edge* sortedEdges = malloc(m * sizeof(Edge));
        memcpy(sortedEdges, edges, m * sizeof(Edge));
    
        // 对边按费用排序
        for (int i = 0; i < m; i++)
            for (int j = i + 1; j < m; j++)
                if (sortedEdges[i].cost > sortedEdges[j].cost) {
                    Edge temp = sortedEdges[i];
                    sortedEdges[i] = sortedEdges[j];
                    sortedEdges[j] = temp;
                }
    
        for (int i = 0; i < m; i++) {
            int x = find(parent, sortedEdges[i].src);
            int y = find(parent, sortedEdges[i].dest);
    
            if (x != y) {
                minimum_cost += sortedEdges[i].cost;
                union_op(parent, rank, x, y);
            }
        }
    
        free(sortedEdges);
    
        return minimum_cost;
    }
    
    int main() {
        int n, m;
        scanf("%d %d", &n, &m);
    
        Edge edges[m];
        for (int i = 0; i < m; i++) {
            scanf("%d %d %d", &edges[i].src, &edges[i].dest, &edges[i].cost);
        }
    
        printf("Minimum cost using Prim's algorithm: %d\n", primMST(edges, n, m));
        printf("Minimum cost using Kruskal's algorithm: %d\n", kruskalMST(edges, n, m));
    
        return 0;
    }
    

    这段代码首先读取输入数据,然后调用 Prim 和 Kruskal 算法计算最小生成树的最小成本,并将结果打印到控制台上。

    请注意,这个程序没有处理错误输入的情况,例如输入的边数量超过实际可能的最大值(n*(n-1)/2)。在实际应用中,你应该添加适当的错误检查和异常处理代码。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(4条)

报告相同问题?

问题事件

  • 系统已结题 5月5日
  • 已采纳回答 4月27日
  • 创建了问题 4月20日