top1编程
← 返回题目
题解

【提高】关押罪犯

1 条题解

  • 0
    @ 2026-7-29 0:18:17
    #include<bits/stdc++.h>
    using namespace std;
    
    const int N = 2e5 + 10;  // 数组大小设为2倍罪犯数量(N≤20000)
    const int inf = 0x3f3f3f3f;  // 定义一个无穷大常量(虽然本题未使用)
    
    struct node {
        int x, y, z;  // 存储罪犯对:x和y是罪犯编号,z是怨气值
    };
    
    node t[N];  // 存储所有罪犯关系
    int n, m;   // n-罪犯数量,m-关系数量
    int f[N];   // 并查集父节点数组
    
    // 比较函数:按怨气值从大到小排序
    bool cmp(node a, node b) {
        return a.z > b.z;
    }
    
    // 并查集查找函数(带路径压缩)
    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;  // 将fy的父节点设为fx
    }
    
    int main() {
        cin >> n >> m;
        
        // 输入所有罪犯关系
        for(int i = 1; i <= m; i++) 
            cin >> t[i].x >> t[i].y >> t[i].z;
        
        // 按怨气值从大到小排序(贪心处理)
        sort(t + 1, t + 1 + m, cmp);
        
        // 初始化并查集:1~n表示监狱A,n+1~2n表示监狱B
        for(int i = 1; i <= 2 * n; i++) 
            f[i] = i;
        
        // 处理每条关系(从怨气值大的开始处理)
        for(int i = 1; i <= m; i++) {
            int x = t[i].x, y = t[i].y;
            
            // 如果x和y已经在同一集合(即被分到同一监狱)
            if(find(x) == find(y)) {
                cout << t[i].z;  // 直接输出当前怨气值(因为是排序后第一个冲突)
                return 0;
            }
            else {
                // 将x和y分到不同监狱:
                // x在A则y在B,x在B则y在A
                merge(x, y + n);  // x和y的"敌人"(y+n)合并
                merge(y, x + n);  // y和x的"敌人"(x+n)合并
            }
        }
        
        // 如果没有冲突发生
        cout << 0;
        return 0;
    }
    
    • 1