Solution CF1242B 0-1 MST
题目大意:给定一张完全图,其中有(m)条边权值为(1)其它为(0),(n leq 10 ^ 5,m leq min(frac{n(n-1)}{2},10^5))求最小生成树
暴力
分析:假如我们可以把所有(0)边都连上的话答案显而易见是联通块的个数减一
关键是我们不可能把图给建出来啊,我们可以只存(1)边,然后没有保存的边就是(0)边了
然后如果每个点(O(n))枚举的话复杂度太高了,我们找到一个联通块就把里面所有的点打上标记,每次枚举没有标记的点即可
由于绝大部分的边都是(0)边,所以跑的很快。
极限情况下全都是(1)边,可以卡到(n^2logn)但是这样点数最多只有(10^3),所以比较稳
#include <iostream>
#include <map>
#include <set>
#include <vector>
using namespace std;
const int maxn = 1e5 + 100;
int ans,n,m;
map<int,int> G[maxn];
set<int> s;
void dfs(int u){
vector<int> tmp;
for(int v : s)
if(G[u].find(v) == G[u].end())tmp.push_back(v);
for(int v : tmp)s.erase(v);
for(int v : tmp)dfs(v);
}
int main(){
cin >> n >> m;
for(int u,v,i = 1;i <= m;i++)
cin >> u >> v,G[u][v] = G[v][u] = 1;
for(int i = 1;i <= n;i++)s.insert(i);
while(!s.empty()){
int u = *s.begin();s.erase(u);
dfs(u);
ans++;
}
cout << ans - 1 << '
';
return 0;
}