40pts 染色+并查集求助
查看原帖
40pts 染色+并查集求助
749714
xyzfrozen楼主2023/12/5 15:03

i 和 i+n 表示正反点

col 表示每个点最终的颜色,¬xj,xj,T,F,U\lnot x_j,x_j,T,F,U 等

然后 dfsdfs 边权 0/10/1 表示颜色相等/不相等

#include<bits/stdc++.h>
#define pt putchar(' ')
#define nl puts("")
#define pi pair<int,int>
#define pb push_back
#define go(it) for(auto &it:as[x])
using namespace std;

const int N=2e5+10;
int n,m,T,F,U;
int col[N],p[N],sz[N];
vector<pi> as[N];

int fr(){
	int x=0,flag=1;
	char ch=getchar();
	while(ch<'0' || ch>'9'){
		if(ch=='-') flag=-1;
		ch=getchar();
	}
	while(ch>='0' && ch<='9'){
		x=x*10+(ch-'0');
		ch=getchar();
	}
	return x*flag;
}
void fw(int x){
	if(x<0) putchar('-'),x=-x;
	if(x>9) fw(x/10);
	putchar(x%10+'0');
}
int max(int a,int b){return a>b?a:b;}
int min(int a,int b){return a<b?a:b;}
int change(char c)
{
	if(c=='T') return T;
	if(c=='F') return F;
	return U;
}

int find(int x)
{
	if(x!=p[x]) p[x]=find(p[x]);
	return p[x];
}
void merge(int x,int y)
{
	int px=find(x),py=find(y);
	if(px^py) p[px]=py,sz[py]+=sz[px];
}
int other(int x)
{
	if(col[x]=='T') return F;
	if(col[x]=='F') return T;
	if(col[x]=='U') return U;
	return (col[x]>=n)?(col[x]-n):(col[x]+n);
}

bool dfs(int x,int c)
{
	col[x]=c;
	go(it)
	{
		int v=it.first,w=it.second;
		if(!~col[v] && !dfs(v,col[x]^w)) return 0;
		else if(col[v]!=(col[x]^w)) return 0;
	}
	return 1;
}

void solve()
{
	n=fr(),m=fr();
	memset(col,0,sizeof col);
	memset(p,0,sizeof p);
	T=2*n+1,F=2*n+3,U=2*n+2;
	for(int i=1;i<=(n<<1)+3;i++)
		col[i]=p[i]=i,sz[i]=(i<=n);
	while(m--)
	{
		char op[2];
		scanf("%s",op);
		if(op[0]=='+' || op[0]=='-')
		{
			int u=fr(),v=fr();
			if(op[0]=='+') col[u]=col[v];
			else col[u]=other(v);
		}
		else col[fr()]=change(op[0]);
	}

	for(int i=1;i<=n;i++)
	{
		if(col[i]>2*n) as[i].pb({col[i],0}),as[col[i]].pb({i,0}),merge(col[i],i);
		else if(col[i]>n) as[i].pb({col[i]-n,1}),as[col[i]-n].pb({i,1}),merge(col[i]-n,i);
		else as[i].pb({col[i],0}),as[col[i]].pb({i,0}),merge(col[i],i);
	}
	
	int ans=0;
	memset(col,-1,sizeof col);
	dfs(U,1),ans+=sz[find(U)];
	
	for(int i=1;i<=2*n;i++)
		if(find(i)!=find(U) && find(i)==i && !dfs(i,1))
			ans+=sz[i];
	fw(ans),nl;
}

int main()
{
	int c=fr(),T=fr();
	while(T--) solve();
	return 0;
}
2023/12/5 15:03
加载中...