Codeforces Round #441 (Div. 1, by Moscow Team Olympiad) F. Royal Questions

本文介绍了一种基于最大基环树算法解决的问题:如何在限制条件下实现最优匹配以获得最大的总权重。具体场景为王子与公主间的婚姻配对,通过构建特定的图结构并运用算法找到最优解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

F. Royal Questions

Problem Statement

    In a medieval kingdom, the economic crisis is raging. Milk drops fall, Economic indicators are deteriorating every day, money from the treasury disappear. To remedy the situation, King Charles Sunnyface decided make his n sons-princes marry the brides with as big dowry as possible.
    In search of candidates, the king asked neighboring kingdoms, and after a while several delegations arrived with m unmarried princesses. Receiving guests, Karl learned that the dowry of the i th princess is wi of golden coins.
    Although the action takes place in the Middle Ages, progressive ideas are widespread in society, according to which no one can force a princess to marry a prince whom she does not like. Therefore, each princess has an opportunity to choose two princes, for each of which she is ready to become a wife. The princes were less fortunate, they will obey the will of their father in the matter of choosing a bride.
    Knowing the value of the dowry and the preferences of each princess, Charles wants to play weddings in such a way that the total dowry of the brides of all his sons would be as great as possible. At the same time to marry all the princes or princesses is not necessary. Each prince can marry no more than one princess, and vice versa, each princess can marry no more than one prince.
    Help the king to organize the marriage of his sons in the most profitable way for the treasury.

Input

    The first line contains two integers n, m (2 ≤ n ≤ 200 000, 1 ≤ m ≤ 200 000) — number of princes and princesses respectively.
    Each of following m lines contains three integers ai, bi, wi (1 ≤ ai, bi ≤ n, ai ≠ bi, 1 ≤ wi ≤ 10 000) — number of princes, which i-th princess is ready to marry and the value of her dowry.

Output

    Print the only integer — the maximum number of gold coins that a king can get by playing the right weddings.

Examples

Example 1
    Input
        2 3
        1 2 5
        1 2 1
        2 1 10
    Output
        15
Example 2
    Input
        3 2
        1 2 10
        3 2 20
    Output
        30

题意

    一共有n个王子,m个公主,给出第i个公主可以嫁给的两个王子ai,bi以及嫁妆ci,每个王子只能娶一个公主,公主只能在两个中选一个,求最大嫁妆。

思路

    其实这题一看题目,我是一脸懵逼的,但是听机房内的dalao说是最大基环树,后来看看题,发现真的是个最大基环树..其实关于题意,我们可以理解为有n个点,m条边,aibi间有一条长度为ci的边,那么问题就转化为从中选几条边并给每条边定向,使每个点的度数不超过1。容易发现最终答案是一个基环树,求一个最大基环树就好了。

Code

#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
bool Finish_read;
template<class T>
inline void read(T &x) {
    Finish_read=0;x=0;int f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    x*=f;Finish_read=1;
}
template<class T>
inline void write(T x) {
    if(x/10!=0)
        write(x/10);
    putchar(x%10+'0');
}
template<class T>
inline void writeln(T x) {
    write(x);
    putchar('\n');
}
/*================Header Template==============*/
const int maxn=200010;
struct Edge{
    int u,v,w;
    Edge(){}
    Edge(int a,int b,int c):u(a),v(b),w(c){}
}e[maxn];
bool vis[maxn];
int f[maxn],cnt,n,m,x,y,z,ans;
inline bool cmp(Edge a,Edge b){return a.w>b.w;}
inline int findfa(int x){return x==f[x]?x:f[x]=findfa(f[x]);}
int main() {
    read(n);
    read(m);
    for(int i=1;i<=n;i++) {
        f[i]=i;
        vis[i]=0;
    }
    for(int i=1;i<=m;i++) {
        read(x);
        read(y);
        read(z);
        e[++cnt]=Edge(x,y,z);
    }
    sort(e+1,e+cnt+1,cmp);
    for(int i=1;i<=cnt;i++) {
        int u=findfa(e[i].u),v=findfa(e[i].v);
        if(u==v) {
            if(vis[u])
                continue;
            vis[u]=1;
            ans+=e[i].w;
        }
        else {
            if(vis[u]&&vis[v])
                continue;
            vis[u]|=vis[v];
            f[v]=u;
            ans+=e[i].w;
        }
    }
    writeln(ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值