gym102392 J.Graph and Cycles

J.Graph and Cycles

题目链接

题意

给定一个 n n n个顶点的无向完全图 n n n奇数,有 n ( n − 1 ) 2 \frac{n(n-1)}{2} 2n(n1)条边),每条边 e i ( u , v ) e_i(u,v) ei(u,v)有一个权值 w [ i ] w[i] w[i]

需要将所有的边分成若干个集合(设集合数量为 m m m),每条边只能属于一个集合 S i S_i Si

任意一个集合 S i = { e 1 ( u 1 , v 1 ) , e 2 ( u 2 , v 2 ) , e 3 ( u 3 , v 3 ) } S_i=\{e_1(u_1,v_1),e_2(u_2,v_2),e_3(u_3,v_3)\} Si={e1(u1,v1),e2(u2,v2),e3(u3,v3)}需要满足:(这个集合是有一定顺序的,详细的可以看英文题目)

在这里插入图片描述

且定义这个集合的权值为:
∑ i = 1 ∣ S i ∣ − 1 M a x ( w [ i ] , w [ i + 1 ] ) + M a x ( w [ ∣ S i ∣ ] , w [ 1 ] ) \sum_{i=1}^{|S_i|-1}Max(w[i],w[i+1])+Max(w[|S_i|],w[1]) i=1Si1Max(w[i],w[i+1])+Max(w[Si],w[1])
定义这 m m m个集合总的权值为: ∑ i = 1 m v a l ( S i ) \sum_{i=1}^{m}val(S_i) i=1mval(Si) v a l ( S i ) val(S_i) val(Si)指集合 S i S_i Si的权值。

问这个总权值的最小值是多少。

思路

题解思路特别巧妙,将边的问题,转化成点的问题。

所有顶点的度数均为偶数,若 e a e_a ea是从 v e r ver ver点进去的边, e b e_b eb是从 v e r ver ver出去的边,则可以将这两条边组成一个 P a i r ( e a , e b ) Pair(e_a,e_b) Pair(ea,eb)

定义这个 P a i r ( e a , e b ) Pair(e_a,e_b) Pair(ea,eb)属于同一个集合,且 e a e_a ea e b e_b eb的公共顶点是 u u u,则该 P a i r ( e a , e b ) Pair(e_a,e_b) Pair(ea,eb)对该集合的贡献是 M a x ( w [ a ] , w [ b ] ) Max(w[a],w[b]) Max(w[a],w[b]),为使最终结果更小,要使得这个值尽可能的小,可以将与点 u u u相连的边从小到大排序然后两两取出(可以感性理解一下,具体证明我就不写了)。

在这里插入图片描述

每个顶点都有 n − 1 2 \frac{n-1}{2} 2n1 P a i r ( e a , e b ) Pair(e_a,e_b) Pair(ea,eb),则对于这个点来说,点 u u u对结果的贡献是:
v a l ( u ) = ∑ i n − 1 2 M a x ( w [ a i ] , w [ b i ] ) val(u)=\sum_{i}^{\frac{n-1}{2}}Max(w[a_i],w[b_i]) val(u)=i2n1Max(w[ai],w[bi])

AC的代码

#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int N = 1000 + 10;

int n;
vector<int> vec[N];
int main() {
    cin >> n;
    for (int i = 1; i <= n * (n - 1) / 2; i++) {
        int u, v, w;
        cin >> u >> v >> w;
        vec[u].push_back(w);
        vec[v].push_back(w);
    }
    for (int i = 1; i <= n; i++) sort(vec[i].begin(), vec[i].end());

    ll res = 0;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j < vec[i].size(); j += 2) res += vec[i][j];
    cout << res;
    return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值