zoukankan      html  css  js  c++  java
  • Codeforces Round #599 (Div. 2) D. 0-1 MST (补图连通块计数)

     

    Ujan has a lot of useless stuff in his drawers, a considerable part of which are his math notebooks: it is time to sort them out. This time he found an old dusty graph theory notebook with a description of a graph.

    It is an undirected weighted graph on nn vertices. It is a complete graph: each pair of vertices is connected by an edge. The weight of each edge is either 00 or 11; exactly mm edges have weight 11, and all others have weight 00.

    Since Ujan doesn't really want to organize his notes, he decided to find the weight of the minimum spanning tree of the graph. (The weight of a spanning tree is the sum of all its edges.) Can you find the answer for Ujan so he stops procrastinating?

    Input

    The first line of the input contains two integers nn and mm (1n1051≤n≤105, 0mmin(n(n1)2,105)0≤m≤min(n(n−1)2,105)), the number of vertices and the number of edges of weight 11 in the graph.

    The ii-th of the next mm lines contains two integers aiai and bibi (1ai,bin1≤ai,bi≤n, aibiai≠bi), the endpoints of the ii-th edge of weight 11.

    It is guaranteed that no edge appears twice in the input.

    Output

    Output a single integer, the weight of the minimum spanning tree of the graph.

    Examples
    input
    Copy
    6 11
    1 3
    1 4
    1 5
    1 6
    2 3
    2 4
    2 5
    2 6
    3 4
    3 5
    3 6
    
    output
    Copy
    2
    
    input
    Copy
    3 0
    
    output
    Copy
    0
    
    Note

    The graph from the first sample is shown below. Dashed edges have weight 00, other edges have weight 11. One of the minimum spanning trees is highlighted in orange and has total weight 22.

    In the second sample, all edges have weight 00 so any spanning tree has total weight 00.

     

     

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <cstdlib>
    #include <map>
    #include <vector>
    #include <set>
    #include <queue>
    #include <stack>
    #include <cmath>
    using namespace std;
    #define mem(s,t) memset(s,t,sizeof(s))
    #define pq priority_queue
    #define pb push_back
    #define fi first
    #define se second
    #define ac return 0;
    #define ll long long
    #define cin2(a,n,m)     for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>a[i][j];
    #define rep_(n,m)  for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)
    #define rep(n) for(int i=1;i<=n;i++)
    #define test(xxx) cout<<"  Test  " <<" "<<xxx<<endl;
    #define TLE std::ios::sync_with_stdio(false);   cin.tie(NULL);   cout.tie(NULL);   cout.precision(10);
    #define lc now<<1
    #define rc now<<1|1
    #define ls now<<1,l,mid
    #define rs now<<1|1,mid+1,r
    #define half no[now].l+((no[now].r-no[now].l)>>1)
    #define ll long long
    #define inf 0x3f3f3f3f
    #define mod 1000000007
    const int mxn = 1e5+10;
    int n,m,k,ans,col,t,flag,vis[mxn];
    ll dp[mxn],pro[mxn];
    string str,ch ;
    map<char,int>mp;
    set<int>st,G[mxn];
    pair <int,int> pa[mxn];
    bool cmp(pair<int,int>x,pair<int,int>y)
    {
        return x.first>y.first;
    }
    void BFS(int x)
    {
        queue<int>q;
        q.push(x);
        st.erase(x);
        while(q.size())
        {
            int now = q.front();
            q.pop();
            if(vis[now])
                continue;
            vis[now] = 1 ;
            for(set<int>::iterator it=st.begin(); it!=st.end();)
            {
                int cnt = *it;
                it++;//set和vector这些容器不能边修改边遍历,需要在修改之前将迭代器往后加一
                if(G[now].find(cnt)==G[now].end())
                {
                    q.push(cnt);
                    st.erase(cnt);
                }
            }
        }
    }
    int main()
    {
        cin>>n>>m;
        for(int i=1; i<=n; i++)
            st.insert(i);
        for(int i=1; i<=m; i++)
        {
            cin>>col>>ans;
            G[col].insert(ans);
            G[ans].insert(col);
        }
        ans = 0;
        for(int i=1; i<=n; i++)
        {
            if(!vis[i])
            {
                BFS(i);
                ans++;
            }
        }
        cout<<ans-1<<endl;
        return 0;
    }

     

    //聚聚:并查集,用set存已经被放入并查集的点,对于没有放入的点,计算该点和联通块相连的点的个数,如果相连的点的个数小于联通块大小,则直接连进去即可。时间复杂度O(n+m∗log)
    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1e6+100;
    int par[N],siz[N];
    int cnt[N];
    struct edge{
        int u,v,w;
    }e[N];
    vector<int> G[N];
    int find(int x){
        return x==par[x]?x:par[x]=find(par[x]);
    }
    void unite(int x,int y){
        x=find(x);
        y=find(y);
        if(x==y) return ;
        par[x]=y;
        siz[y]+=siz[x];
    }
    int main(){
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
        int n,m,u,v;
        cin>>n>>m;
        for(int i=1;i<=n;i++){
            par[i]=i;
            siz[i]=1;
        }
        for(int i=1;i<=m;i++){
            cin>>u>>v;
            G[u].push_back(v);
            G[v].push_back(u);
        }
        int ans=n-1;
        set<int> st;
        st.insert(1);
        for(int i=2;i<=n;i++){
            for(int v:G[i]){
                cnt[find(v)]++;//和各联通块相连的点的个数
            }
            for(auto it=st.begin();it!=st.end();){
                int an=find(*it);
                if(cnt[an]<siz[an]){
                    unite(*it,i);
                    st.erase(it++);
                    ans--;
                }else it++;
            }
            for(int v:G[i]) cnt[find(v)]=0;
            st.insert(i);
        }
        cout<<ans<<endl;
        return 0;
    }
    所遇皆星河
  • 相关阅读:
    开博
    jmeter插件安装
    eclipse清理项目缓存
    java.lang.UnsupportedClassVersionError: JVMCFRE003解决方法--jdk 1.6 中switch的参数无法使用String类型
    转:Eclipse Memory Analyzer入门学习笔记
    转发: 探秘Java中的String、StringBuilder以及StringBuffer
    Java.net.SocketException: Unrecognized Windows Sockets error: 0: JVM_Bind异常
    windows 查看端口是否被占用
    iostat命令
    计算机原码、补码、反码与java移位运算符(<</>>/>>>)
  • 原文地址:https://www.cnblogs.com/Shallow-dream/p/11853785.html
Copyright © 2011-2022 走看看