对于有向图: 对于一条边u,v 若uv在一个集合内则成环
对于无向图:用强向量判断
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#include<queue>
#include <string>
#include <sstream>
#include <map>
#include <vector>
#define LL long long
#define N 1000100
#pragma comment(linker, "/STACK:102400000,102400000")
vector<int>g[N];
int n,m1,m2;
int DFN[N],Low[N],Stack[N],Time,top;
int taj,Belong[N],ok;
bool Instack[N];
void tarjan(int u,int fa)
{
DFN[u]=Low[u]=++Time;
Stack[top++] = u;
Instack[u]=1;
for(int i=0;i<g[u].size();i++)
{
int v=g[u][i];
if(DFN[v]==-1)
{
tarjan(v,u);
Low[u]=min(Low[u],Low[v]);
}
else if(Instack[v]) Low[u]=min(Low[u],DFN[v]);
}
if(Low[u]==DFN[u])
{
int now,num=0;
taj++;
do{
now=Stack[--top];
Instack[now]=0;
Belong[now]=taj;
num++;
if(num>1) ok=1;//两个点成环
}while(now!=u);
}
}
void tarjan_init(int all)
{
memset(DFN,-1,sizeof(DFN));
memset(Instack,0,sizeof(Instack));
top=Time=taj=0;
for(int i=1;i<=all;++i)
if(DFN[i]==-1) tarjan(i,i);
}
int fa[N];
int find(int a)
{
if(a!=fa[a])
return fa[a]=find(fa[a]);
else return fa[a];
}
int main()
{
int t,a,b;
cin>>t;
while(t--)
{
cin>>n>>m1>>m2;
for(int i=1;i<=n;i++)
g[i].clear(),fa[i]=i;
ok=0;
for(int i=0;i<m1;++i)//无向图
{
scanf("%d%d",&a,&b);
int x=find(a);
int y=find(b);
if(x==y) ok=1;
fa[x]=y;
}
for(int i=0;i<m2;++i)//有向图
{
scanf("%d%d",&a,&b);
int x=find(a);
int y=find(b);
if(x==y) ok=1;
g[x].push_back(y);//集合
}
tarjan_init(n);
if(ok) puts("YES");
else puts("NO");
}
return 0;
}
/*
3 1 2
1 2
1 3
3 2
*/