美文网首页
Codeforces 875F - Royal Question

Codeforces 875F - Royal Question

作者: 费城的二鹏 | 来源:发表于2017-11-15 13:55 被阅读46次

    题目: Codeforces 875F - Royal Questions

    翻译

    n 个王子和 m 个公主,每个公主有两个中意的王子,公主嫁出去的嫁妆是 w。一个王子最多能娶一个公主,一个公主最多能娶一个王子,可以不让所有的公主和王子结婚。求最大嫁妆总数。

    分析

    因为是搜索并查集找到的题目,所以主观就向并查集想了。

    把公主看中的两个王子合到一个集合内,有两种情况。

    1. 集合内王子的数量大于等于公主数量,也就是集合内没有环或者重复的边。此时这个集合内所有公主的嫁妆都可以得到。

    2. 集合内王子的数量小于公主数量,此时,集合内可得到嫁妆的个数等于王子的个数,需要贪心,也就是从大到小取嫁妆值得和。

    因为第二种情况的存在,需要先把公主中意的王子和嫁妆按照嫁妆的大小逆序排列,这样保证,当出现王子数量小于公主数量的情况时,就抛弃新的嫁妆,因为新的嫁妆一定小于等于之前的任何一个嫁妆。

    最后把每个根的总和累加

    代码(C++)

    我程序的 Accepted 截图
    //
    //  main.cpp
    //  ACM
    //
    //  Created by Tconan on 2017/11/8.
    //  Copyright © 2017年 Tconan. All rights reserved.
    //
    
    #include <iostream>
    #include <stdio.h>
    #include <algorithm>
    using namespace std;
    
    int total[200010];
    int root[200010];
    int pairs[200010];
    
    int getRoot(int i) {
        if (root[i] != i) {
            root[i] = getRoot(root[i]);
            return root[i];
        }
        return i;
    }
    
    void merge(int left, int right, int value) {
        left = getRoot(left);
        right = getRoot(right);
        
        if (left == right) {
            if (pairs[left] < 0) {
                total[left] += value;
            }
            pairs[left] = min(1, pairs[left] + 1);
            return;
        }
        
        total[left] += total[right];
        if (pairs[left] < 0 || pairs[right] < 0) {
            total[left] += value;
        }
        pairs[left] += min(1, pairs[right] + 1);
        
        root[right] = left;
    }
    
    struct Point {
        int a;
        int b;
        int w;
    };
    
    bool complare(Point left, Point right) {
        return left.w > right.w;
    }
    
    int main(int argc, const char * argv[]) {
        
        int n, m, sum = 0;
        cin>>n>>m;
        
        for (int i=0; i<=n; ++i) {
            total[i] = 0;
            root[i] = i;
            pairs[i] = -1;
        }
        
        // 开始这个地方写写成了10010,结果报错的信息是 “Time limit exceeded on test 15”
        // 找了半天才发现,改成200010就AC了
        Point points[200010];
        
        int a, b, w;
        for (int i=0; i<m; ++i) {
            cin>>a>>b>>w;
            points[i].a = a;
            points[i].b = b;
            points[i].w = w;
        }
        
        sort(points, points + m, complare);
        
        for (int i=0; i<m; ++i) {
            merge(points[i].a, points[i].b, points[i].w);
        }
        
        for (int i=1; i<=n; ++i) {
            if (root[i] == i) {
                sum += total[i];
            }
        }
        
        cout<<sum<<endl;
        
        return 0;
    }
    
    

    相关文章

      网友评论

          本文标题:Codeforces 875F - Royal Question

          本文链接:https://www.haomeiwen.com/subject/gabcvxtx.html