cf1242B

Posted 033000-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cf1242B相关的知识,希望对你有一定的参考价值。

题意简述:给出一个n个点的完全图,边权要么是1要么是0,输入只给出权值的是1的那些边,求解最小生成树的权值

 

解答:边很多,我们考虑使用prim算法,prim算法的过程中维护了一个dis数组,这里我们可以发现数组的值单调递减,并且只有01两种取值

因此我们考虑用数据结构去加速他,具体来说就是维护两个集合一个集合存1,记为s1,一个存0记为s2

然后最重要的就是如何更新这个dis数组,也就是s1和s2的更新

显然我们只能去选择遍历权值为1的边,因此每加进去一个点,我们遍历他出发的所有的边,显然如果他出现在了s1中,那么这个数还应该出现在s1中,否则他就应该进去s2

这个操作我们可以用通过再加一个set搞定

int n,m;

vector<int> g[maxn];

bool vis[maxn];

int main(){
	cin>>n>>m;
	for(int i=0;i<m;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		g[x].push_back(y);
		g[y].push_back(x);
	}
	vis[1]=1;
	set<int> zero,one;
	for(int i:g[1]){
		if(i!=1) {
			one.insert(i);
		}
	}
	for(int i=2;i<=n;i++)
		if(!one.count(i)) zero.insert(i);
	set<int> t;
	int ans=0;
	for(int cc=0;cc<n-1;cc++){
		int x;
		if(zero.size()) x=*zero.begin(),zero.erase(x);
		else x=*one.begin(),one.erase(x),ans++;
		t.clear();
		vis[x]=1;
		for(auto y:g[x]){
			if(!vis[y]) {
				if(one.count(y)) one.erase(y),t.insert(y);
			}
		}
		for(int y:one)
			zero.insert(y);
		one.clear();
		one=t;
	}
	cout<<ans<<endl;
}

  

 

以上是关于cf1242B的主要内容,如果未能解决你的问题,请参考以下文章

[Codeforces 1242B]0-1 MST

如何从后台弹出片段

cf 模拟

CF1435 游记

无法解析符号 c882c94be45fff9d16a1cf845fc16ec5

本人想学习破解技术但是看不懂反汇编代码!求助!!