扩展域并查集做法60分求条
查看原帖
扩展域并查集做法60分求条
779484
c2105cxy楼主2024/11/1 13:07
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int head[5*N];
char num[5*N];
bool flag[5*N];
int fa[5*N],cnt[5*N];
bool uk[5*N];
int ans;
int find(int x){
	if(x==fa[x])return x;
	else return fa[x]=find(fa[x]);
}
void merge(int x,int y){
	int fx=find(x),fy=find(y);
	if(fx==fy)return;
	fa[fx]=fy;
	cnt[fy]+=cnt[fx];
	cnt[fx]=0;
}
int main(){
	//freopen("tribool3.in","r",stdin);
	int c,t;
	cin>>c>>t;
	while(t--){
		int n,m;
		cin>>n>>m;
		
		for(int i=1;i<=n;i++)num[i]='0',head[i]=i,flag[i]=0;
		for(int i=1;i<=2*n;i++)fa[i]=i,cnt[i]=1,uk[i]=0;
		for(int i=1;i<=m;i++){
			char r;
			int x,y;
			cin>>r>>x;
			if(r=='T'||r=='U'||r=='F'){
				head[x]=x;
				flag[x]=0;
				num[x]=r;
			}
			if(r=='+'){
				cin>>y;
				num[x]='0';
				flag[x]=flag[y];
				head[x]=head[y];
			}
			if(r=='-'){
				cin>>y;
				num[x]='0';
				flag[x]=flag[y]^1;
				head[x]=head[y];
			}
		}
		for(int i=1;i<=n;i++){
			if(head[i]==i&&flag[i]==1){
				flag[i]=0;
				num[i]='U';
			}
			if(num[i]=='T')head[i]=2*n+1,flag[i]=0;
			if(num[i]=='F')head[i]=2*n+1,flag[i]=1;
		}
		fa[2*n+1]=2*n+1,cnt[2*n+1]=1,uk[2*n+1]=0;
		fa[3*n+1]=3*n+1,cnt[3*n+1]=1,uk[3*n+1]=0;
		head[2*n+1]=2*n+1,flag[2*n+1]=0;
		ans=0;
		for(int i=1;i<=n;i++){
			
			int x=i,y=head[i];
			int fx=find(x),fx1=find(x+n),fy=find(y),fy1=find(y+n);
			if(head[i]!=i){
				if(!flag[x]&&fx!=fy){
					merge(x,y);
					if(fx1!=fx&&fy!=fy1)merge(x+n,y+n);
					if(fx==fy1){
						cnt[fy]/=2;
						cnt[fy1]/=2;
					}
				}
				else if(flag[x]&&fx!=fy1){
					merge(x+n,y);
					if(fx1!=fx&&fy!=fy1)merge(x,y+n);
					if(fx==fy){
						cnt[fy]/=2;
						cnt[fy1]/=2;
					}
				}
			}
		}
		
		
		for(int i=1;i<=n;i++){
			int x=i;
			int fx=find(x),fx1=find(x+n);
			if((fx==fx1||num[x]=='U')&&(!uk[fx])){
				ans+=cnt[fx];
				uk[fx]=1;
			}
		}
		cout<<ans<<endl;
		}
	}
	return 0;
}
```cpp
2024/11/1 13:07
加载中...