rt,subtask4 全 WA。
思路与题解略有不同:
首先跑 Tarjan,把图变成一个 DAG。
易证把 DAG 变成全白需要操作的点是固定的(没有一个点被操作两次或以上)。
然后跑拓扑,如果当前点为黑就修改并统计需要修改的点的个数(记为 ans)。
然后就是分类讨论。
要上课,明天回来看。
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
char buf[1<<20],*p1=buf,*p2=buf;
#define getchar() (p1==p2&&(p2=buf+fread(p1=buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
template<typename T>inline void read(T& x){
x=0;char c=getchar();bool f=0;
for(;!isdigit(c);c=getchar())if(c=='-')f=1;
for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+(c^48);
f&&(x=-x);
}
template<typename T,typename... _T>inline void read(T& x,_T&... y){read(x),read(y...);}
const int N=1e5+5,M=2e5+5;
int n,m,deg[N];
int val[N],col[N];
struct edge{int x,y,z,pre;}a[M];int alen,last[N];
void ins(int x,int y,int z=0){a[++alen]={x,y,z,last[x]};last[x]=alen;}
int dfn[N],low[N];
int idx,tot;
int c[N];
int s[N],top;
bool v[N];
void dfs(int x){
dfn[x]=low[x]=++idx;
s[++top]=x,v[x]=1;
for(int k=last[x];k;k=a[k].pre){
int y=a[k].y;
if(!dfn[y]){
dfs(y);
low[x]=min(low[x],low[y]);
}
else if(v[y])
low[x]=min(low[x],dfn[y]);
}
if(low[x]==dfn[x]){
int y;tot++;
do{
y=s[top--];
v[y]=0,c[y]=tot;
}while(y!=x);
}
}
bool check(int x){
if(col[c[x]]==-1)return col[c[x]]=val[x],1;
else return col[c[x]]==val[x];
}
map<int,map<int,bool>>h;
bool Tarjan(){
idx=0;
tot=0;
top=0;
memset(dfn,0,sizeof dfn);
memset(low,0,sizeof low);
memset(v,0,sizeof v);
memset(c,0,sizeof c);
for(int i=1;i<=n;i++)
if(!dfn[i])dfs(i);
int temp=alen;
alen=0,memset(last,0,sizeof last);
memset(deg,0,sizeof deg);
memset(col,-1,sizeof col);
for(auto& x:h)x.second.clear();
for(int i=1;i<=n;i++)
if(!check(i))return 0;
for(int i=1;i<=temp;i++){
int x=a[i].x,y=a[i].y;
if(c[x]!=c[y]&&!h[c[x]][c[y]]){
ins(c[x],c[y]);
h[c[x]][c[y]]=1;
deg[c[y]]++;
}
}
return 1;
}
int q[N],l,r,ans;
bool cnt[N];
void Topo(){
l=1,r=0;
ans=0;
memset(cnt,0,sizeof cnt);
for(int i=1;i<=tot;i++)
if(!deg[i])q[++r]=i;
while(l<=r){
int x=q[l++];
col[x]^=cnt[x];
if(col[x])ans++,col[x]=0,cnt[x]^=1;
for(int k=last[x];k;k=a[k].pre){
int y=a[k].y;
cnt[y]^=cnt[x];
if(!--deg[y])q[++r]=y;
}
}
}
int main(){
int t;read(t);
while(t--){
alen=0;
memset(last,0,sizeof last);
read(n,m);
for(int i=1;i<=n;i++)read(val[i]);
for(int i=1;i<=m;i++){
int x,y;
read(x,y);
ins(x,y);
}
if(!Tarjan()){
putchar('N');
continue;
}
Topo();
if(ans&1){//A不败
if(ans==1)putchar('A');
else putchar('N');
}
else{//B不败
if(ans==2&&ans==tot)putchar('B');
else if(!ans)putchar('B');
else putchar('N');
}
}
}