题意:给定一张n个点的完全图,其中有m条边权为1其余为0,求最小生成树的权值和
n,m<=1e5
思路:答案即为边权为0的边连接的联通块个数-1
用set存图和一个未被选取的点的集合,bfs过程中如果找到边权为0且未被选取的边则加入
如果要维护联通块大小也在bfs里随便记一下就好
具体实现看代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsigned int uint; 5 typedef unsigned long long ull; 6 typedef long double ld; 7 typedef pair<int,int> PII; 8 typedef pair<ll,ll> Pll; 9 typedef vector<int> VI; 10 typedef vector<PII> VII; 11 typedef pair<ll,ll>P; 12 #define N 500010 13 #define M 1000000 14 #define INF 1e9 15 #define fi first 16 #define se second 17 #define MP make_pair 18 #define pb push_back 19 #define pi acos(-1) 20 #define mem(a,b) memset(a,b,sizeof(a)) 21 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++) 22 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--) 23 #define lowbit(x) x&(-x) 24 #define Rand (rand()*(1<<16)+rand()) 25 #define id(x) ((x)<=B?(x):m-n/(x)+1) 26 #define ls p<<1 27 #define rs p<<1|1 28 #define fors(i) for(auto i:e[x]) if(i!=p) 29 30 const int MOD=1e9+7,inv2=(MOD+1)/2; 31 double eps=1e-6; 32 int dx[4]={-1,1,0,0}; 33 int dy[4]={0,0,-1,1}; 34 35 set<int>G[N],S; 36 int vis[N],c[N],ans; 37 38 int read() 39 { 40 int v=0,f=1; 41 char c=getchar(); 42 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 43 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 44 return v*f; 45 } 46 47 ll readll() 48 { 49 ll v=0,f=1; 50 char c=getchar(); 51 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 52 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 53 return v*f; 54 } 55 56 void bfs(int st) 57 { 58 queue<int> q; 59 S.erase(st); 60 q.push(st); 61 int s=1; 62 while(q.size()>0) 63 { 64 int u=q.front(); 65 q.pop(); 66 if(vis[u]) continue; 67 vis[u]=1; 68 69 for(auto it=S.begin();it!=S.end();) 70 { 71 int v=*it; 72 it++; 73 if(G[u].find(v)==G[u].end()) 74 { 75 q.push(v); 76 S.erase(v); 77 s++; 78 } 79 } 80 } 81 c[ans]=s; 82 } 83 84 int main() 85 { 86 int n=read(),m=read(); 87 rep(i,1,n) S.insert(i); 88 rep(i,1,m) 89 { 90 int x=read(),y=read(); 91 G[x].insert(y); 92 G[y].insert(x); 93 } 94 ans=0; 95 rep(i,1,n) 96 if(!vis[i]) 97 { 98 ans++; 99 bfs(i); 100 } 101 printf("%d ",ans); 102 sort(c+1,c+ans+1); 103 rep(i,1,ans) printf("%d ",c[i]); 104 return 0; 105 }