求助本机过大样例,但是RE
查看原帖
求助本机过大样例,但是RE
86633
Shabby_fish楼主2023/11/28 16:21

rt,本机过大样例,洛谷20pts #3~#10RE,CCF官方60pts

玄学并查集做法:

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int sub,t;
int n,m;
bool flag;
int in[100006];
int fa[100006];
int gettt[100006];
int Find(int x)
{
	int tmp=x,tmp2;
	while(fa[x]!=x) x=fa[x];
	while(fa[tmp]!=tmp)
	{
		tmp2=tmp;
		tmp=fa[tmp];
		fa[tmp2]=x;
	}
	return x;
}
int Find2(int x)
{
	int tmp=x;
	while(fa[x]!=x)
	{
		if(gettt[x])
		  break;
		x=fa[x];
	}
	while(fa[tmp]!=tmp&&tmp!=x)
	{
		gettt[tmp]=gettt[x];
		tmp=fa[tmp];
	}
	return x;
}
int main()
{
	cin>>sub>>t;
	while(t--)
	{
		cin>>n>>m;
		int _T=n+1;
		int _F=-n-1;
		int _U=0;
		int ans=0;
		for(int i=0;i<=n+1;i++)
		{
			gettt[i]=0;
			in[i]=fa[i]=i;
		}
		gettt[_U]=-1;
		gettt[_T]=gettt[_F]=1;
		int x,y;
		while(m)
		{
			char ch=getchar();
			switch(ch)
			{
				case '+':cin>>x>>y;in[x]=in[y];break;
				case '-':cin>>x>>y;in[x]=-in[y];break;
				case 'T':cin>>x;in[x]=_T;break;
				case 'F':cin>>x;in[x]=_F;break;
				case 'U':cin>>x;in[x]=_U;break;
				default:m++;
			}
			m--;
		}
		for(int i=1;i<=n;i++)
		{
			int tmpy=Find(abs(in[i]));
			if(i!=tmpy)
			  fa[i]=tmpy;
		}
		for(int i=1;i<=n;i++)
		{
			if(fa[i]==i)
			{
				int now=i;
				bool Unum=1;
				do
				{
					if(in[now]<0)
					{
						Unum=!Unum;
					}
					now=abs(in[now]);
				}while(now!=i);
				if(Unum)
				{
					fa[i]=n+1;
				    do
				    {
				    	gettt[now]=1;
				    	now=abs(in[now]);
				    }while(now!=i);
				}
				else
				{
					fa[i]=0;
    				do
	    			{
		    			gettt[now]=-1;
			    		now=abs(in[now]);
				    }while(now!=i);
				}
			}
		}
		for(int i=1;i<=n;i++)
		{
			if(!gettt[i])
			{
				Find2(i);
			}
		}
		for(int i=1;i<=n;i++)
		{
			if(gettt[i]==-1)
			  ans++;
		}
		cout<<ans<<endl;
	}
	return 0;
}
 
2023/11/28 16:21
加载中...