有双向边,有单向边,问是否存在一点出发,回到出发点,也就是成环
直接深搜一发,在记得回溯边跟点,内存4*maxn
#pragma comment(linker, "/STACK:102400000,102400000")
#include<iostream>
#include<cstdio>
#include<cstring>
const int maxn = 1000005;
using namespace std;
struct node
{
int u,v,next;
};
node e[maxn*4];
int vis[maxn*4], ps[maxn],flag;
int head[maxn],tot;
int n,m1,m2;
void init()
{
memset(head, -1,sizeof(head));
memset(ps, 0,sizeof(ps));
memset(vis, 0,sizeof(vis));
tot = 0;
}
void add(int u,int v)
{
e[tot].u = u;
e[tot].v = v;
e[tot].next = head[u];
head[u] = tot++;
}
void dfs(int u)
{
for(int i = head[u]; i != -1&&!flag; i = e[i].next)
{
int v = e[i].v;
if(!vis[i])
{
if(i<m1*2)
{
vis[i] = vis[i^1] = 1;
}
else
{
vis[i] = 1;
}
if(ps[v])
{
flag = 1;
return;
}
ps[v] = 1;
dfs(v);
ps[v] = 0;
if(i<m1*2)
{
vis[i] = vis[i^1] = 0;
}
else
{
vis[i] = 0;
}
}
}
}
int main()
{
int t,u,v;
scanf("%d",&t);
while(t--)
{
init();
scanf("%d%d%d",&n,&m1,&m2);
for(int i = 0; i < m1; i++)
{
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
for(int i = 0; i < m2; i++)
{
scanf("%d%d",&u,&v);
add(u,v);
}
flag = 0;
for(int i = 1; i <= n && !flag; i++)
{
if(!ps[i])
{
ps[i] = 1;
dfs(i);
ps[i] = 0;
}
}
if(flag)puts("YES");
else puts("NO");
}
return 0;
}