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;	
}
posted @ 2021-02-12 23:07  shuitiangong  阅读(81)  评论(0编辑  收藏  举报