首页 > 其他分享 >Codeforces 1948G MST with Matching

Codeforces 1948G MST with Matching

时间:2024-03-16 16:44:24浏览次数:26  
标签:return int MST Codeforces 1948G fa maxn getfa

因为贡献是两个之和,考虑固定下一个,求解另一个的最优。
\(\text{MST}\) 似乎找不到什么好的办法固定,便考虑固定下最大匹配。

对于树的最大匹配,考虑到因为树也是二分图,所以树的最大匹配 \(=\) 最小点覆盖。

考虑如果知道了最小点覆盖内的点,那就说明如果一条边两个端点都不在点集中,是不可能出现在这个对应的树中的,因为没有被覆盖。
于是把至少有一个端点在点集中的边集拎出来跑 \(\text{MST}\) 即可。

因为 \(n\) 的规模较小,可以直接枚举最小点覆盖的点集求解。

时间复杂度 \(O(n^2\log n^2 + 2^nn^2)\)。

代码
#include<bits/stdc++.h>
const int maxn = 20 + 5, maxm = maxn * maxn;
struct Eg {int u, v, w;};
std::vector<Eg> E;
int fa[maxn];
int getfa(int x) {return fa[x] == x ? x : (fa[x] = getfa(fa[x]));}
inline bool merge(int x, int y) {x = getfa(x), y = getfa(y); return x == y ? false : (fa[x] = y, true);}
int main() {
    int n, c; scanf("%d%d", &n, &c);
    for (int i = 0; i < n; i++) for (int j = 0, x; j < n; j++) {
        scanf("%d", &x);
        x && (E.push_back({i, j, x}), 1);
    }
    std::sort(E.begin(), E.end(), [&](const auto &a, const auto &b) {return a.w < b.w;});
    long long ans = LLONG_MAX;
    for (int s = 0; s < (1 << n); s++) {
        long long tot = 1ll * c * __builtin_popcount(s);
        std::iota(fa, fa + n, 0);
        int cnt = n;
        for (auto _ : E) (s & (1 << _.u | 1 << _.v)) && merge(_.u, _.v) && (cnt--, tot += _.w);
        cnt == 1 && (ans = std::min(ans, tot));
    }
    printf("%lld\n", ans);
    return 0;
}

标签:return,int,MST,Codeforces,1948G,fa,maxn,getfa
From: https://www.cnblogs.com/rizynvu/p/18077249

相关文章

  • Educational Codeforces Round 163 A-E
    A.SpecialCharacters构造。形如\(A\)和\(B\)这类单个字符构成的字符串对答案的贡献为\(0\),而\(AA\)和\(AAAA\)这类多个相同字符构成的字符串对答案的贡献固定为\(2\)​,则无法构造出奇数值,由第二类字符串拼接即可构造出偶数值。时间复杂度:\(O(n)\)。#include<bit......
  • Codeforces 1948E Clique Partition
    考虑到有\(|i-j|\),所以肯定是让相邻的一部分在一个团里。考虑构造出一个最长长度的,后面类似复制几遍即可。考虑到\(|k-1|=k-1\),且因为\(a_i\)为一个排列,差的绝对值至少为\(1\),所以只考虑两端最长长度也只可能为\(k\)。不妨先假设最长长度为\(k\)来构造。那么......
  • Codeforces-1005C
    https://codeforces.com/problemset/problem/1005/C一、代码目录#include<bits/stdc++.h>usingnamespacestd;voidsolve(){inta[122222],n,ans=0;map<int,int>m;scanf("%d",&n);for(inti=0;i<n;i++){......
  • Educational Codeforces Round 163 (Rated for Div. 2)
    EducationalCodeforcesRound163(RatedforDiv.2)A-SpecialCharacters解题思路:一个相同的连续段会贡献两个特殊字符,所以答案一定是偶数,找个不同的数分隔开即可。代码:#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;usingpii=pair<ll,ll......
  • numpy中random.seed()与random.RandomState()的区别
    1.random.seed()用处:初始化随机数生成器。设置随机数生成器种子后,直接生成随机数即可,无需在随机数生成器条件下运行。2.random.RandomState()作用:获得随机数生成器 比较上面两图可以看出,获取随机数生成器之后,必须在此条件下运行,才可生成相同的随机数,若不在此条件下运行,随......
  • Codeforces Round 933 (Div. 3)赛后总结
    CodeforcesRound933(Div.3)B从边缘开始计算,因为边缘肯定只能一个一个减,就可以遍历得到答案.代码C只要对mapie特判,然后判断map和pie的个数就是答案了。D(记忆化搜索)可以通过二维数组来标记搜索状态,将已经出现过的状态直接返回,极大减少时间。#include<bits/stdc++.h>......
  • Codeforces Round 933 (Div. 3) A - G 题解
    CodeforcesRound933(Div.3)A-RudolfandtheTicketSolution因为\(n\)很小,直接枚举\(b_i+c_j\)所产生的所有数字Code#include<bits/stdc++.h>usingnamespacestd;voidsolve(){intn,m,k;cin>>n>>m>>k;intans=0;......
  • CodeForces 1874E Jellyfish and Hack
    洛谷传送门CF传送门显然\(\text{fun}(P)_{\max}=\frac{|P|(|P|+1)}{2}\)。考虑大力dp,设\(f_{i,j,k}\)为\(|P|=i\),\(P_1=j\),\(\text{fun}(P)=k\)的排列\(P\)的个数。此时\(|L|=j-1,|R|=i-j\)。转移枚举\(L_1,R_1,\text{fun}(L),\text{fun}(R......
  • Codeforces Round 933 (Div. 3)
    CodeforcesRound933(Div.3)AA-RudolfandtheTicket暴力查看代码voidsolve(){intn,m,k;cin>>n>>m>>k;vector<int>b(n),c(m);for(inti=0;i<n;++i)cin>>b[i];for(inti=0;i<m;++i)cin>>c[i];......
  • Codeforces Round 933 (Div. 3)
    CodeforcesRound933(Div.3)A-RudolfandtheTicket解题思路:暴力。代码:#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;usingpii=pair<ll,ll>;#definefifirst#definesesecondusingpiii=pair<ll,pair<ll,ll>&......