警钟敲烂!!!
查看原帖
警钟敲烂!!!
421736
You_Quiet楼主2022/11/12 09:10

如果在合并函数里进行联通块数量的改动,一定要判断,在处理最后联通块个数时不要改值, (希望你能看懂吧)

rt

正确代码:

void he(int x,int y,bool op){
	int root_x=find(x);
	int root_y=find(y);
	if(root_x!=root_y){
		if(op==1&&v[root_y]!=1&&v[root_x]!=1) root--;
		v[root_x]=0;
		v[root_y]=0;
		if(root_x>root_y) swap(root_x,root_y);
		f[root_y]=root_x;
	}
}

错误代码:

void he(int x,int yp){
	int root_x=find(x);
	int root_y=find(y);
	if(root_x!=root_y){
		if(v[root_y]!=1&&v[root_x]!=1) root--;
		v[root_x]=0;
		v[root_y]=0;
		if(root_x>root_y) swap(root_x,root_y);
		f[root_y]=root_x;
	}
}

最开始的加边

for(int i=1;i<=m;i++){
		if(v[edge[i].from]==0&&v[edge[i].to]==0) {
			he(edge[i].from,edge[i].to,0);
		}
	}
	for(int i=0;i<=n-1;i++){
		int r=find(i);
		if(v1[r]==0&&v[r]==0){
			v1[r]=1;
			root++;
		}
	}

反向加点时的操作

for(int i=k;i>=1;i--){
		root++;
		int Next=a[i];
		int flag=0;
		v[Next]=0;
		for(int o=0;o<bian[Next].size();o++){
			int N=bian[Next][o];
			if(have[N]==1){
				if(v[N]==1) root++;
				v[N]=0;
				he(Next,N,1);
			} 
		}
		have[Next]=1;
		ans[i-1]=root;
	}

但愿你能理解我什么意思吧

可能只有我犯这种很low的错误

2022/11/12 09:10
加载中...