最小生成树

繁华的都市

这是一个**最小生成树(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;
}
相关推荐
致Great3 小时前
科研人的 AI,不该只回答问题:我用字节TraeWork 跑了一遍真实研究任务
算法
纵有疾風起3 小时前
线性表的定义与基本操作 — 从逻辑结构到 ADT 接口
数据结构·算法·408·线性表·adt
测试_AI_一辰4 小时前
AI Agent 评测最隐蔽的坑-记忆
人工智能·算法·ai·自动化·ai编程
lucas_AI4 小时前
给YOLO检测器插 LoRA,'插对地方'比'插什么'更要命
人工智能·算法
LuminousCPP4 小时前
数据结构-时间与复杂度|时间/空间复杂度 + 两道力扣练习 + 二分查找复盘
c语言·数据结构·经验分享·算法·leetcode
Nil2084 小时前
leetcode 三数之和
数据结构·算法·leetcode
小小龙学IT5 小时前
C++ std::vector 底层实现深度解析:内存布局、扩容策略、移动语义与迭代器失效
开发语言·c++·算法
noipp5 小时前
推荐题目:洛谷 P16689 出征
java·开发语言·数据结构·c++·算法·洛谷·luogu
eBest数字化转型方案5 小时前
从工程视角拆解冰柜资产管理:拍照识别 pipeline、纯净度算法与 IoT 选型踩坑
人工智能·物联网·算法
Interview Aid1125 小时前
Roblox OA 面经|小游戏+编程双修,Coding 两题满分通过
算法