#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; }