Topic links: point I ah ╭ (╯ ^ ╰) ╮
Subject to the effect:
complete graph points
given
edges, the right side of
,
other side is right
minimum spanning tree
Problem-solving ideas:
Title number of connected block diagram into complementing
each enumeration one unprocessed point, a wide-search
and enumerate the original on each side, marked with marker
points and unlabeled certain point enumeration complement FIG belonging to a communication block
these queued unlabeled point, a wide-search
optimization processing chain with points, points on the treated delete list
time complexity:
The total complexity of enumeration side is:
enumerated points are divided into two cases:
①: the point is not marked, the queued each point only once enqueue
②: the point has been marked, the time complexity of the operator
inner
Core: Pictured chain optimization complement dense map
#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
using pii = pair <ll,int>;
const int maxn = 2e5 + 5;
int n, m, ans[maxn], cnt;
int l[maxn], r[maxn];
int vis[maxn], vis2[maxn];
vector <int> g[maxn];
inline void del(int x){
l[r[x]] = l[x];
r[l[x]] = r[x];
}
void bfs(int x){
vis[x] = ans[++cnt] = 1;
queue <int> Q;
Q.push(x); del(x);
while(Q.size()){
int q = Q.front(); Q.pop();
for(auto v : g[q])
if(!vis[v]) vis2[v] = 1;
for(int i=r[0]; i; i=r[i])
if(!vis2[i]) {
Q.push(i);
del(i);
vis[i] = 1;
++ans[cnt];
} else vis2[i] = 0;
}
}
int main() {
scanf("%d%d", &n, &m);
for(int i=1, u, v; i<=m; i++) {
scanf("%d%d", &u, &v);
g[u].push_back(v);
g[v].push_back(u);
}
for(int i=0; i<=n; i++) l[i] = i-1, r[i] = i+1;
r[n] = 0;
for(int i=1; i<=n; i++)
if(!vis[i]) bfs(i);
printf("%d\n", cnt - 1);
}