30 求调
查看原帖
30 求调
1236488
JIIING楼主2024/8/6 19:59

思路:与团伙类似

#include<bits/stdc++.h>
using namespace std;
int t,n,m,x,y,tot;
int a[1000086],fa[1000086];
bool flag[1000086];
int foe[1000086];//某数的“敌人”,即 -x[i] 
int find(int x)
{
	if(fa[x]!=x)
	{
		return fa[x]=find(fa[x]);	
	}
	else return fa[x];
}
void unnion(int x,int y)
{
	int a=find(x);
	int b=find(y);

	fa[a]=b;
}
int main()
{
	char s;
	int c;
	
	cin>>c>>t;
	
	for(int z=1;z<=t;z++)
	{
		tot=0;
	
		cin>>n>>m;
		for(int i=1;i<=n;i++)
		{
			foe[i]=0;
			flag[i]=false;
			fa[i]=i;
			a[i]=i;
		}	//多测清零 
		
		for(int i=1;i<=m;i++)
		{
		cin>>s;
		if(s=='T')
		{
		scanf("%d",&x);

		flag[x]=false;
		}
		if(s=='F')
		{
		scanf("%d",&x);

		flag[x]=false;	
		}
		if(s=='U')
		{
		scanf("%d",&x);
		flag[x]=true;	
		}
		if(s=='-')
		{
			scanf("%d%d",&x,&y);
			a[x]=a[y]*(-1);
			
			if(x==y && foe[x]==x)//特判 
			{
				foe[x]=0;
//				cout<<x<<endl;
//				cout<<foe[x]<<endl;
				continue;
			}
			if(foe[x])unnion(foe[x],y);
			else foe[x]=y;
			
			if(foe[y])unnion(foe[y],x);
			else foe[y]=x; 
			//“敌人的敌人就是朋友”,负负得正 
			if(flag[fa[y]])
			{
			unnion(x,y);
			flag[x]=true;
			cout<<"*"<<endl;
			}
		}
		if(s=='+')
		{
			scanf("%d%d",&x,&y);
			a[x]=a[y];
			unnion(x,y);
		}
			
		}
		for(int i=1;i<=n;i++)
		{
			int b=find(i);
			if(b==find(foe[i]))//如果“敌人的朋友是朋友”,那么明显矛盾,即为 U 
			{
			flag[b]=true;
//			cout<<b<<" "<<foe[i]<<" "<<endl;
//			cout<<"***"<<endl;
			}
			if(a[i]==-i)flag[b]=true;

//			if(flag[i]=true)flag[fa[i]]=true;
		}
		/*for(int i=1;i<=n;i++)cout<<a[i]<<" ";
		cout<<endl;
	for(int i=1;i<=n;i++)
		{
			cout<<find(i)<<" ";
		}
		cout<<endl;
		for(int i=1;i<=n;i++)
		{
			cout<<fa[i]<<" ";
		}
		cout<<endl;*/
		for(int i=1;i<=n;i++)
		{
			if(flag[fa[i]])tot++;
		}
		cout<<tot<<endl;

		
		
	}
	
	
	return 0;
}
2024/8/6 19:59
加载中...