最小生成树

繁华的都市

这是一个**最小生成树(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;
}
相关推荐
W23035765737 小时前
经典算法:最长上升子序列(LIS)深度解析 C++ 实现
开发语言·c++·算法
minji...8 小时前
Linux 线程同步与互斥(三) 生产者消费者模型,基于阻塞队列的生产者消费者模型的代码实现
linux·运维·服务器·开发语言·网络·c++·算法
语戚8 小时前
力扣 968. 监控二叉树 —— 贪心 & 树形 DP 双解法递归 + 非递归全解(Java 实现)
java·算法·leetcode·贪心算法·动态规划·力扣·
skywalker_118 小时前
力扣hot100-7(接雨水),8(无重复字符的最长子串)
算法·leetcode·职场和发展
bIo7lyA8v10 小时前
算法稳定性分析中的输入扰动建模的技术9
算法
CoderCodingNo10 小时前
【GESP】C++三级真题 luogu-B4499, [GESP202603 三级] 二进制回文串
数据结构·c++·算法
sinat_2869451910 小时前
AI Coding 时代的 TDD:从理念到工程落地
人工智能·深度学习·算法·tdd
炽烈小老头10 小时前
【 每天学习一点算法 2026/04/12】x 的平方根
学习·算法
ASKED_201910 小时前
从排序到生成:腾讯广告算法大赛 2025 baseline解读
人工智能·算法