https://codeforces.com/contest/1344/problem/C
这题没考虑顺序问题,比赛完以后才测出来WA5。。。
首先,对所有ji->ki,连边,再同时建立他的反向图,然后有环的话,由于边是表示<,所以有环无解
那么我们依次考虑每一个i,如果他已经在正向图或者反向图中被访问过了,说明他跟x[1]-x[i-1]中某个数有大小关系,则说明他只能选E,如果没有,则可以选A
然后再去正向图和反向图中分别dfs,把他能影响到相对关系的全部打上标记。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxl=3e5+10;
int n,m,ans,cas;
int a[maxl],b[maxl],rudu[maxl];
char s[maxl];
vector<int> e[maxl],re[maxl];
queue<int> q;
bool vis1[maxl],vis2[maxl];
inline void prework()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
rudu[i]=0,e[i].clear(),s[i]='E';
for(int i=1;i<=m;i++)
{
scanf("%d%d",&a[i],&b[i]);
e[a[i]].push_back(b[i]);
re[b[i]].push_back(a[i]);
rudu[b[i]]++;
}
while(!q.empty()) q.pop();
ans=0;int sum=0,u;
for(int i=1;i<=n;i++)
if(rudu[i]==0)
q.push(i);
while(!q.empty())
{
u=q.front();sum++;q.pop();
for(int v : e[u])
{
rudu[v]--;
if(!rudu[v])
q.push(v);
}
}
if(sum!=n)
ans=-1;
}
inline void dfs1(int u)
{
vis1[u]=true;
for(int v:e[u])
if(!vis1[v])
dfs1(v);
}
inline void dfs2(int u)
{
vis2[u]=true;
for(int v:re[u])
if(!vis2[v])
dfs2(v);
}
inline void mainwork()
{
if(ans<0)
return;
for(int i=1;i<=n;i++)
{
if(vis1[i] || vis2[i]) s[i]='E';
else s[i]='A',ans++;
if(!vis1[i]) dfs1(i);
if(!vis2[i]) dfs2(i);
}
}
inline void print()
{
if(ans<0)
puts("-1");
else
{
printf("%d\n",ans);
for(int i=1;i<=n;i++)
printf("%c",s[i]);
puts("");
}
}
int main()
{
int t=1;
//scanf("%d",&t);
for(cas=1;cas<=t;cas++)
{
prework();
mainwork();
print();
}
return 0;
}