题意:有两个实验室,有n个实验和m对实验依赖(a,b)(a,b)代表实验bb必须在实验aa之后才能进行,一开始可以在任意两个实验室进行实验,问最少要转移多少次实验室可以把这n个实验全部完成。
两次拓扑排序分别计算从1号实验室开始和从2号实验室开始所需要转移的次数就可以。。。
代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int MAXN = 100000+1;
int n,m,T;
struct Edge {
int to,next;
Edge(){}
Edge(int _to,int _next):to(_to),next(_next){}
}e[1000000+5];
int head[100000+1],tot;
void init(){
for(int i=1;i<=n;i++)head[i]=-1;
// memset(head,-1,sizeof(head));
tot=0;
}
void AddEdge(int u,int v){
e[tot]=Edge(v,head[u]);
head[u]=tot++;
}
void Read(int &x){
char ch;
while((ch=getchar())&&!isdigit(ch));
x=0;
do {
x=(x<<1)+(x<<3)+(ch^48);
}while((ch=getchar())&&isdigit(ch));
}
int que1[MAXN*2],que2[MAXN*2];
int front1,rear1,front2,rear2;
int du[MAXN],type[MAXN],du1[MAXN];

int countt(){
front1=rear1=front2=rear2=0;
//memcpy(du1,du,sizeof(du));
for(int i=1;i<=n;i++){
du1[i]=du[i];
if(du[i]==0){
if(type[i]==1) que1[rear1++]=i;
if(type[i]==2) que2[rear2++]=i;
--du[i];
}
}
int cnt=0;
int pre=1;
//if(rear1==0)pre=2;
//else pre=1;
while((front1!=rear1)||(front2!=rear2)){
int tf=0;
while(front1!=rear1){
tf=1;
int u=que1[front1++];
for(int i=head[u];i!=-1;i=e[i].next){
int v=e[i].to;
du[v]--;
if(du[v]==0){
if(type[v]==1)que1[rear1++]=v;//q1.push(v);
if(type[v]==2)que2[rear2++]=v;//q2.push(v);
du[v]--;
}
}
}
if(tf&&pre!=1){
pre=1;++cnt;
}
tf=0;
while(front2!=rear2){
tf=1;
int u=que2[front2++];
for(int i=head[u];i!=-1;i=e[i].next){
int v=e[i].to;
du[v]--;
if(du[v]==0){
if(type[v]==1)que1[rear1++]=v;//q1.push(v);
if(type[v]==2)que2[rear2++]=v;//q2.push(v);
du[v]--;
}
}
}
if(tf&&pre!=2){
pre=2;++cnt;
}
}

// memcpy(du,du1,sizeof(du));
front1=rear1=front2=rear2=0;
for(int i=1;i<=n;i++){
du[i]=du1[i];
if(du[i]==0){
if(type[i]==1)que1[rear1++]=i;//q1.push(i);
if(type[i]==2)que2[rear2++]=i;//q2.push(i);
--du[i];
}
}
int cnt1=0;
pre=2;
while((front1!=rear1)||(front2!=rear2)){
int tf=0;
while(front2!=rear2){
tf=1;
int u=que2[front2++];
for(int i=head[u];i!=-1;i=e[i].next){
int v=e[i].to;
du[v]--;
if(du[v]==0){
if(type[v]==1)que1[rear1++]=v;//q1.push(v);
if(type[v]==2)que2[rear2++]=v;//q2.push(v);
du[v]--;
}
}
}
if(tf&&pre!=2){
pre=2;++cnt1;
}
tf=0;
while(front1!=rear1){
tf=1;
int u=que1[front1++];
for(int i=head[u];i!=-1;i=e[i].next){
int v=e[i].to;
du[v]--;
if(du[v]==0){
if(type[v]==1)que1[rear1++]=v;//q1.push(v);
if(type[v]==2)que2[rear2++]=v;//q2.push(v);
du[v]--;
}
}
}
if(tf&&pre!=1){
pre=1;++cnt1;
}
}
return cnt<cnt1?cnt:cnt1;

//return cnt;
}
int main()
{
//while(~scanf("%d",&T))
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
init();memset(du,0,sizeof(du));
for(int i=1;i<=n;i++) Read(type[i]);//scanf("%d",&type[i]);
for(int i=0,x,y;i<m;i++){
// scanf("%d%d",&x,&y);
Read(x),Read(y);
AddEdge(x,y);

++du[y];
}
printf("%d\n",countt());
}
return 0;
}