zoukankan      html  css  js  c++  java
  • [CF1242B] 0-1 MST

    有一张完全图,(n) 个节点,有 (m) 条边的边权为 (1),其余的都为 (0),这 (m) 条边会给你。问你这张图的最小生成树的权值。

    Solution

    (1) 边视为不存在,那么最后的答案就是 (0) 边形成的连通块数 (-1)

    顺序扫描所有点,对于点 (i),枚举由 ([1,i-1]) 已经形成的集合 (j),如果 (i)(j) 连的边数小于 (j) 的大小,那么就表明一定有 (0) 边,于是将 (i) 所在集合与集合 (j) 合并

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 500005;
    
    int n,m,t1,t2,fa[N],sz[N],bel[N];
    vector <int> g[N];
    
    int find(int p) {
        return p==fa[p] ? p : fa[p]=find(fa[p]);
    }
    
    void merge(int p,int q) {
        p=find(p); q=find(q);
        if(p!=q) {
            fa[p]=q;
            sz[q]+=sz[p];
        }
    }
    
    signed main() {
        ios::sync_with_stdio(false);
        vector <int> st;
        cin>>n>>m;
        for(int i=1;i<=m;i++) {
            cin>>t1>>t2;
            g[max(t1,t2)].push_back(min(t1,t2));
        }
        for(int i=1;i<=n;i++) {
            fa[i]=i;
            sz[i]=1;
        }
        for(int i=1;i<=n;i++) {
            map<int,int> cnt;
            for(int j:g[i]) cnt[find(j)]++;
            for(int j:st) {
                if(find(i)==find(j)) continue;
                if(cnt[find(j)]<sz[find(j)]) merge(i,j);
            }
            if(find(i)==i) st.push_back(i);
        }
        int ans=0;
        for(int i=1;i<=n;i++) if(find(i)==i) ++ans;
        cout<<ans-1;
    }
    
    
  • 相关阅读:
    Android
    nodejs 中 接受前端的数据请求的处理
    nodejs 文件操作
    nodejs 简单的搭建一个服务器
    angular 的跨域处理
    angular 的配置文件的应用
    angular 语法的应用
    淘宝的公共样式
    web编辑器的快捷键
    scss 用法 及 es6 用法讲解
  • 原文地址:https://www.cnblogs.com/mollnn/p/12564108.html
Copyright © 2011-2022 走看看