#include<stdio.h> #include<string.h> #define N 21000 struct node { int v,next; }bian[51000]; int yong,dfn[N],low[N],stac[N],top,index,visit[N],ans,flag,mark[N],head[N],pre[N]; void init() {//初始化 memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(mark,0,sizeof(mark)); memset(visit,0,sizeof(visit)); memset(head,-1,sizeof(head)); memset(pre,0,sizeof(pre)); flag=0;yong=0; index=0;top=0;ans=0; memset(stac,0,sizeof(stac)); } void addedge(int u,int v) { bian[yong].v=v; bian[yong].next=head[u]; head[u]=yong++; } int MIN(int a,int b) { return a>b?b:a; } void judge(int v,int u) {//对于每一个强连通分量对边的两边的点增一 while(pre[u]!=v) { mark[u]++; if(mark[u]>1) { flag=1;return ; } u=pre[u]; } return ; } void tarjan(int u) { dfn[u]=low[u]=++index; stac[++top]=u; visit[u]=1; int i; for(i=head[u];i!=-1;i=bian[i].next) { int v=bian[i].v; if(dfn[v]==0) { pre[v]=u; tarjan(v); if(flag) return ; low[u]=MIN(low[u],low[v]); } else if(visit[v]) { judge(v,u); if(flag)return ; low[u]=MIN(low[u],dfn[v]); } } if(dfn[u]==low[u]) { ans++; if(ans>1){//判断是否是一个强联通图 flag=1;return ; } int t; do{ t=stac[top--]; visit[t]=0; }while(t!=u); } return ; } int main() { int t,n,a,b,i; scanf("%d",&t); while(t--) { init(); scanf("%d",&n); while(scanf("%d%d",&a,&b),a||b) { addedge(a,b); } for(i=0;i<n;i++) { if(!dfn[i]) tarjan(i); if(flag)break; } if(flag==0) printf("YES "); else printf("NO "); } return 0; }