CodeForces - 1242B 0-1 MST(求补图连通块个数)
题目大意
给你几条边,这些边是从完全图里删除掉的边,将一条边入删边之后的完全图的花费是1,问最小生成树的代价。
解题思路
图中连通块的个数求出来了就有答案了,求补图连通块个数模板题。
代码
const int maxn = 2e5+10;
const int maxm = 1e5+10;
int n, m;
bool vis[maxn];
set<int> st, e[maxn];
void bfs(int u) {
queue<int> q;
q.push(u);
st.erase(u);
vis[u] = 1;
while(!q.empty()) {
int t = q.front(); q.pop();
auto it = st.begin();
while(it!=st.end()) {
int v = *it++;
if (!e[v].count(t)) { //该点在删去的边中找不到,说明一定是补图中的点
st.erase(v);
q.push(v);
vis[v] = 1;
}
}
}
}
int main(){
cin >> n >> m;
int ans = 0;
for (int i = 1, a, b; i<=m; ++i) {
cin >> a >> b;
e[a].insert(b);
e[b].insert(a);
}
for (int i = 1; i<=n; ++i) st.insert(i);
int cnt = 0;
for (int i = 1; i<=n; ++i)
if (!vis[i]) {
++cnt;
bfs(i); //每次将一个补图中的连通块消去
}
cout << cnt-1 << endl;
return 0;
}