P2121 拆地毯

解题思路

问题分析

  1. 题目描述:从m条地毯中选择最多k条,要求选出的地毯不形成环,且美丽度之和最大

  2. 关键限制

    • 选出的地毯不能形成环(即形成森林)

    • 最多选k条地毯

    • 需要最大化美丽度总和

算法选择

  1. 最大生成森林:这是最小生成树(MST)问题的变种

  2. Kruskal算法变形

    • 按美丽度降序排序

    • 贪心地选择美丽度大的边

    • 使用并查集避免环的形成

    • 在选够k条边或形成生成树时停止

实现步骤

  1. 预处理

    • 读取所有地毯信息

    • 按美丽度从大到小排序

  2. 核心算法

    • 初始化并查集

    • 遍历排序后的边,选择不形成环的边

    • 累计美丽度,直到选够k条边或无法继续选择

  3. 终止条件

    • 已选k条边

    • 或已形成生成树(选n-1条边)

正确性证明

  1. 贪心选择:每次选择当前最大美丽度的有效边,确保局部最优导致全局最优

  2. 无环保证:通过并查集确保不会连接已连通的顶点

  3. 结果最优:由于从大到小选择,最终的和必然是最大的可能值

复杂度分析

  1. 排序:O(m log m)(主要瓶颈)

  2. Kruskal:O(m α(n))(α为反阿克曼函数)

  3. 总体:O(m log m),对于m≤1e5完全可行

关键点说明

  1. 排序方向:按美丽度降序排序(与标准Kruskal相反)

  2. 停止条件:两个条件满足其一即可停止

  3. 并查集作用:高效管理连通分量,避免环的形成

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;

// 定义边的结构体:x和y是顶点,z是美丽度(权重)
struct node {
    int x, y, z;
};

node a[N];  // 存储所有地毯(边)信息
int n, m, k; // n:区域数, m:地毯数, k:最多保留地毯数
int f[N];   // 并查集数组

// 并查集查找函数(带路径压缩)
int find(int x) {
    if(f[x] != x) f[x] = find(f[x]);
    return f[x];
}

// 并查集合并函数
void merge(int x, int y) {
    int fx = find(x), fy = find(y);
    f[fy] = fx;
}

// 边按美丽度从大到小排序的比较函数
bool cmp(node a, node b) {
    return a.z > b.z;
}

// Kruskal算法变形实现
void kruskal() {
    // 初始化并查集
    for(int i = 1; i <= n; i++) f[i] = i;
    
    int sum = 0, ans = 0; // sum:已选边数, ans:美丽度总和
    
    // 遍历所有边(已按美丽度降序排序)
    for(int i = 1; i <= m; i++) {
        int x = a[i].x, y = a[i].y;
        
        // 如果两点不在同一连通块
        if(find(x) != find(y)) {
            merge(x, y);  // 合并连通块
            sum++;        // 已选边数+1
            ans += a[i].z; // 累加美丽度
            
            // 达到k条边或已形成生成树时停止
            if(sum == k || sum == n - 1) break;
        }
    }
    
    cout << ans; // 输出最大美丽度和
}

int main() {
    cin >> n >> m >> k;
    
    // 读取所有地毯信息
    for(int i = 1; i <= m; i++) {
        cin >> a[i].x >> a[i].y >> a[i].z;
    }
    
    // 按美丽度降序排序
    sort(a + 1, a + 1 + m, cmp);
    
    // 执行算法
    kruskal();
    
    return 0;
}

 

posted @ 2025-04-28 22:01  CRt0729  阅读(15)  评论(0)    收藏  举报