WA60pts并查集做法求调
查看原帖
WA60pts并查集做法求调
627293
FanMingxuan楼主2024/4/19 13:35

大样例tribool4没过

思路: 先把每个变量最终变成了谁的初值记录到a数组,再把每个变量和他的最终值合并到一个集合,之后枚举每个变量,如果和自己的反变量在一个集合就把这个集合打标记,最后枚举每个变量,如果所在集合被打上了标记就ans+1

code:

#include<bits/stdc++.h>
using namespace std;
const int N = 200005;
const int vU = 200001;
const int vT = 200002;
const int vF = 200003;

int n,m;
int a[N << 2];

int T(int x,int state){
	if(x == vU) return vU;
	if(x == vT){
		if(state) return vT;
		return vF;
	}
	if(x == vF){
		if(state) return vF;
		return vT;
	}
	if(state) return x + N + 5;
	return x;
}

int rT(int x){
	if(x > N) return -(x - N - 5);
	return x;
}

namespace Set{
	int f[N << 2];
	
	void init(int n){
		for(int i = 1;i <= n;++ i){
			f[i] = i;
		}
	}
	
	int find(int w){
		if(f[w] == w) return w;
		return find(f[w]);
	}
	
	void merge(int x,int y){
		x = find(x),y = find(y);
		if(x == y) return;
		f[x] = y;
	}
}

bool fail[N << 2];

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int c,t;
	cin>>c>>t;
	while(t --){
		cin>>n>>m;
		Set::init((N << 2) - 1);
		memset(fail,0,sizeof(fail));
		for(int i = 1;i <= (N << 1) + 5;++ i){
			a[T(i,1)] = T(i,1);
			a[T(i,0)] = T(i,0);
		}
		for(int i = 1;i <= m;++ i){
			char op;
			cin>>op;
			switch(op){
				case('T'):{
					int x;
					cin>>x;
					a[T(x,1)] =	T(vT,1);
					a[T(x,0)] = T(vT,0);
					break;
				}
				case('F'):{
					int x;
					cin>>x;
					a[T(x,1)] = T(vF,1);
					a[T(x,0)] = T(vF,0);
					break;
				}
				case('U'):{
					int x;
					cin>>x;
					a[T(x,1)] = T(vU,1);
					a[T(x,0)] = T(vU,0);
					break;
				}
				case('+'):{
					int x,y;
					cin>>x>>y;
					a[T(x,1)] = a[T(y,1)];
					a[T(x,0)] = a[T(y,0)];
					break;
				}
				case('-'):{
					int x,y;
					cin>>x>>y;
					a[T(x,1)] = a[T(y,0)];
					a[T(x,0)] = a[T(y,1)];
					break;
				}
			}
		}
//		for(int i = 1;i <= n;++ i){
//			cout<<"?"<<i<<" "<<T(i,1)<<"\n";
//			cout<<T(i,1)<<" <- "<<a[T(i,1)]<<"\n";
//			cout<<T(i,0)<<" <- "<<a[T(i,0)]<<"\n";
//		}
		for(int i = 1;i <= n;++ i){
			Set::merge(T(i,1),a[T(i,1)]);
			Set::merge(T(i,0),a[T(i,0)]);
		}
		for(int i = 1;i <= n;++ i){
			int g0 = Set::find(T(i,0));
			int g1 = Set::find(T(i,1));
			if(g0 == g1) fail[g1] = true;
		}
		int ans = 0;
		for(int i = 1;i <= n;++ i){
			if(fail[Set::find(T(i,1))]) ans ++;
		}
		cout<<ans<<"\n";
	}
	return 0;
}
2024/4/19 13:35
加载中...