这一题关键是弄懂题意:
我们是从x1开始按顺序执行条件。
比如
3 2
3 1
1 2
这个样例:
A1,E2,E3 是可行的。(我一开始一位从入度为0的做为条件判断起点,但题意并不是,看最后一段,感觉还是有点模棱两可,可能是我的英语理解不太行)
也就是说:x1,x2,x3,x4,x5……
必须先执行id小的变量,即先执行1是A还是E,然后2是A还是E,以此类推。
理清题意,其实这题很简单:
对于a<b:
如果有个语句xa -> xb,若xa是A,则xb一定是E,如果xa是E,则xb也必须是E。
如果有个语句xb -> xa, 若xa是A,则xb一定是E,如果xa是E,则xb也必须是E。
综上:对于一个变量,它取到A时,所有可达它或它可达的变量,都必须是E,且id越小的变量,取A越优。(不然只会白白让一它可达和可达它的变量不能取A)
所以直接从id小到达遍历,正反dfs标记。当前id能取A就取A。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 2e5+7;
vector<int>G1[M],G2[M];
int du[M];
int vs1[M],vs2[M];
void dfs1(int x)
{
vs1[x]=1;
for(auto y:G1[x])
if(!vs1[y])
dfs1(y);
}
void dfs2(int x)
{
vs2[x]=1;
for(auto y:G2[x])
if(!vs2[y])
dfs2(y);
}
char p[M];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n,m;
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int u,v;
cin>>u>>v;
G1[u].pb(v);
G2[v].pb(u);
du[v]++;
}
queue<int>q;
int f=1;
for(int i=1;i<=n;i++)if(du[i]==0)q.push(i);
while(q.size())
{
int x=q.front();q.pop();
for(auto y:G1[x])
{
du[y]--;
if(du[y]==0)q.push(y);
}
}
for(int i=1;i<=n;i++)if(du[i]!=0)f=0;
if(f)
{
int ans=0;
for(int i=1;i<=n;i++)
{
if(vs1[i]||vs2[i])p[i]='E';
else p[i]='A',ans++;
dfs1(i);
dfs2(i);
}
cout<<ans<<endl;
for(int i=1;i<=n;i++)cout<<p[i];
cout<<endl;
}
else cout<<-1<<endl;
return 0;
}