最小生成树

繁华的都市

这是一个**最小生成树(MST)**问题,要求:

1.连接所有节点(连通图)

2.边数最少 → 正好是 n−1 条(生成树)

3.在满足前两条下,最大边权最小 → 最小生成树中的最大边权

算法思路:

1.使用 Kruskal 或 Prim 求最小生成树。

2.Kruskal 按边权从小到大排序,用并查集维护连通性。

3.生成树中的最大边权就是答案。

注意:输出格式要求输出两个整数:选出的边数 和 最大边权。

1.边数一定是 n−1(因为保证连通)。

2.最大边权是生成树中最大的边权。

cs 复制代码
#include <stdio.h>
#include <stdlib.h>

#define MAX_N 305
#define MAX_M 100005

typedef struct {
    int u, v, w;
} Edge;

Edge edges[MAX_M];
int parent[MAX_N];

// 并查集:查找根
int find(int x) {
    if (parent[x] != x)
        parent[x] = find(parent[x]);
    return parent[x];
}

// 并查集:合并
void union_set(int x, int y) {
    int rx = find(x);
    int ry = find(y);
    if (rx != ry)
        parent[rx] = ry;
}

// 比较函数,用于排序
int cmp(const void* a, const void* b) {
    Edge* e1 = (Edge*)a;
    Edge* e2 = (Edge*)b;
    return e1->w - e2->w;
}

int main() {
    int n, m;
    scanf("%d %d", &n, &m);

    for (int i = 0; i < m; i++) {
        scanf("%d %d %d", &edges[i].u, &edges[i].v, &edges[i].w);
    }

    // 按权值排序
    qsort(edges, m, sizeof(Edge), cmp);

    // 初始化并查集
    for (int i = 1; i <= n; i++) {
        parent[i] = i;
    }

    int edge_count = 0;
    int max_weight = 0;

    // Kruskal
    for (int i = 0; i < m; i++) {
        int u = edges[i].u;
        int v = edges[i].v;
        int w = edges[i].w;

        if (find(u) != find(v)) {
            union_set(u, v);
            edge_count++;
            if (w > max_weight)
                max_weight = w;
        }
        if (edge_count == n - 1)
            break;
    }

    printf("%d %d\n", edge_count, max_weight);
    return 0;
}

城市规划大师

cs 复制代码
#include <stdio.h>
#include <stdlib.h>

#define MAXN 1005
#define MAXM (MAXN * MAXN)   // 完全图边数

typedef struct {
    int u, v, w;
} Edge;

Edge edges[MAXM];
int parent[MAXN];
int ban[MAXN][MAXN];  // 禁止边标记

int n, k;
int x[MAXN], y[MAXN];
int edge_cnt = 0;

int abs(int a) { return a < 0 ? -a : a; }
int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }

// 曼哈顿距离
int manhattan(int i, int j) {
    return abs(x[i] - x[j]) + abs(y[i] - y[j]);
}

int cmp(const void* a, const void* b) {
    return ((Edge*)a)->w - ((Edge*)b)->w;
}

int find(int x) {
    if (parent[x] != x)
        parent[x] = find(parent[x]);
    return parent[x];
}

void union_set(int x, int y) {
    int rx = find(x);
    int ry = find(y);
    if (rx != ry)
        parent[rx] = ry;
}

int main() {
    scanf("%d %d", &n, &k);
    
    for (int i = 1; i <= n; i++) {
        scanf("%d %d", &x[i], &y[i]);
    }
    
    // 初始化禁止边
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            ban[i][j] = 0;
    
    for (int i = 0; i < k; i++) {
        int u, v;
        scanf("%d %d", &u, &v);
        ban[u][v] = 1;
        ban[v][u] = 1;
    }
    
    // 生成所有允许的边
    edge_cnt = 0;
    for (int i = 1; i <= n; i++) {
        for (int j = i + 1; j <= n; j++) {
            if (ban[i][j]) continue;  // 禁止边跳过
            edges[edge_cnt].u = i;
            edges[edge_cnt].v = j;
            edges[edge_cnt].w = manhattan(i, j);
            edge_cnt++;
        }
    }
    
    // Kruskal
    qsort(edges, edge_cnt, sizeof(Edge), cmp);
    
    for (int i = 1; i <= n; i++)
        parent[i] = i;
    
    int total = 0;
    int cnt = 0;
    for (int i = 0; i < edge_cnt; i++) {
        int u = edges[i].u;
        int v = edges[i].v;
        int w = edges[i].w;
        if (find(u) != find(v)) {
            union_set(u, v);
            total += w;
            cnt++;
            if (cnt == n - 1)
                break;
        }
    }
    
    printf("%d\n", total);
    return 0;
}
相关推荐
三品吉他手会点灯17 小时前
C语言学习笔记 - 43.运算符与表达式 - 运算符1 - 运算符的分类和简单介绍
c语言·笔记·学习·算法
VkN2X2X4b18 小时前
算法复杂度的实验验证与误差分析的技术8
算法
其利天下技术18 小时前
风扇灯无刷电机自适应算法实战指南
算法·cocos2d·无刷电机自适应算法·bldc驱动自适应算法·其利无刷电机驱动算法
8Qi818 小时前
LeetCode 494:目标和(Target Sum)—— 题解 ✅
算法·leetcode·职场和发展·动态规划·01背包
hujinyuan2016018 小时前
2026年3月 中国电子学会青少年软件编程(Python)三级考试试卷 真题及答案
java·python·算法
froyoisle19 小时前
CSP-J 历年复赛 T1 及解析(2019~2025)
数据结构·c++·算法·csp-j·csp·算法竞赛·信息学
珊瑚里的鱼19 小时前
【动态规划】打家劫舍Ⅱ
算法·动态规划
chao18984419 小时前
SGM(Semi-Global Matching)立体匹配算法 — C++ 实现
开发语言·c++·算法
黎阳之光19 小时前
数智赋能水厂全链路安全|黎阳之光以视频孪生技术落地供水精细化管控
人工智能·物联网·算法·安全·数字孪生
NOVAnet202320 小时前
AI 全球化部署网络瓶颈:算法模型跨地域、跨云互联核心痛点解析
算法·ai·sd-wan·专线·跨区域