比赛 CSP2022提高组 评测结果 WWWAAAAAEEEETTTTEEEE
题目名称 星战 最终得分 25
用户昵称 ZRQ 运行时间 9.717 s
代码语言 C++ 内存使用 10.03 MiB
提交时间 2022-10-30 12:29:32
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#define ll long long
using namespace std;
const int N=100005;
int n,m,q,tot,cnt[N],st[N],top,scc,scnt[N],sc[N],df[N],lw[N],clk;
bool vis[N],svis[N];
char ch;
vector<int> to[N],rv[N],sto[N];
map<pair<int,int>,bool> des;
inline void read(int &x){x=0;ch=getchar();while(ch<48||ch>57)ch=getchar();while(ch>47&&ch<58)x=(x<<3)+(x<<1)+(ch^48),ch=getchar();}
void tarjan(int cur)
{
	df[cur]=lw[cur]=++clk;
	st[++top]=cur;
	vis[cur]=1;
	for(int i=0;i<to[cur].size();++i)
	{
		if(des[{cur,to[cur][i]}]==1) continue;
		if(!df[to[cur][i]]) tarjan(to[cur][i]),lw[cur]=min(lw[cur],lw[to[cur][i]]);
		else if(vis[to[cur][i]]) lw[cur]=min(lw[cur],df[to[cur][i]]);
	}
	if(df[cur]==lw[cur])
	{
		int x;
		++scc;
		do
		{
			x=st[top--];
			vis[x]=0;
			sc[x]=scc;
			++scnt[scc];
		}while(x!=cur);
	}
	return ;
}
bool check()
{
	memset(df,0,sizeof(df));
	memset(lw,0,sizeof(lw));
	scc=0;
	top=0;
	clk=0;
	memset(vis,0,sizeof(vis));
	for(int i=1;i<=n;++i) if(!df[i]) tarjan(i);
	queue<int> q;
	for(int i=1;i<=n;++i)
		for(int j=0;j<to[i].size();++j)
			if(des[{i,to[i][j]}]==0&&sc[to[i][j]]!=sc[i])
				sto[sc[to[i][j]]].push_back(sc[i]);
	for(int i=1;i<=scc;++i) if(scnt[i]>1) q.push(i);
	memset(svis,0,sizeof(svis));
	int ct=0;
	while(!q.empty())
	{
		int cur=q.front();
		q.pop();
		if(svis[cur]) continue;
		svis[cur]=1;
		++ct;
		for(int i=0;i<sto[cur].size();++i)
			if(!svis[cur])
				q.push(sto[cur][i]);
	}
	return ct==scc;
}
int main()
{
	freopen("csp2022_galaxy.in","r",stdin);
	freopen("csp2022_galaxy.out","w",stdout);
	read(n),read(m);
	for(int i=1,u,v;i<=m;++i) read(u),read(v),to[u].push_back(v),rv[v].push_back(u),++cnt[u];
	for(int i=1;i<=n;++i) if(cnt[i]==1) ++tot;
	read(q);
	for(int i=1,t,u,v;i<=q;++i)
	{
		read(t),read(u);
		if(t==1)
		{
			read(v);
			if(des[{u,v}]!=1)
			{
				
				des[{u,v}]=1;
				if(cnt[u]==2) ++tot;
				else if(cnt[u]==1) --tot;
				--cnt[u];
			}
		}
		else if(t==2)
		{
			for(int i=0;i<rv[u].size();++i)
			{
				if(des[{rv[u][i],u}]==1) continue;
				des[{rv[u][i],u}]=1;
				if(cnt[rv[u][i]]==2) ++tot;
				else if(cnt[rv[u][i]]==1) --tot;
				--cnt[rv[u][i]];
			}
		}
		else if(t==3)
		{
			read(v);
			if(des[{u,v}]!=0)
			{
				des[{u,v}]=0;
				++cnt[u];
				if(cnt[u]==1) ++tot;
				else if(cnt[u]==2) --tot;
			}
		}
		else
		{
			for(int i=0;i<rv[u].size();++i)
			{
				if(des[{rv[u][i],u}]==0) continue;
				des[{rv[u][i],u}]=0;
				++cnt[rv[u][i]];
				if(cnt[rv[u][i]]==1) ++tot;
				else if(cnt[rv[u][i]]==2) --tot;
			}
		}
		if(tot==n&&(n==3||check())) puts("YES");
		else puts("NO");
	}
	return 0;
 }