比赛 |
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;
}