题意:
给出一个图,这个图有无向边和有向边,每次从一个点走到另外一个点对应的路就是塌掉,问一个点经过其他回来的这种路是否存在。
题解:
其实就是求是否存在一个环!那么dfs即可。标记边和定点。
#pragma comment(linker, "/STACK:102400000,102400000") #include<iostream> #include<math.h> #include<stdio.h> #include<algorithm> #include<string.h> #include<vector> #include<queue> #include<map> #include<set> #define B(x) (1<<(x)) using namespace std; typedef long long ll; void cmax(int& a,int b){ if(b>a)a=b; } void cmin(int& a,int b){ if(b<a)a=b; } void cmax(ll& a,ll b){ if(b>a)a=b; } void cmin(ll& a,ll b){ if(b<a)a=b; } void add(int& a,int b,int mod){ a=(a+b)%mod; } void add(ll& a,ll b,ll mod){ a=(a+b)%mod; } const int oo=0x3f3f3f3f; const int MOD=1000000007; const double eps = 1e-8; const int maxn = 2000005; const int maxm = 4000005; struct EDGE{ int v,next; }E[maxm]; int head[maxn],tol; int vis[maxn],visl[maxm]; int n,m1,m2; void Init(){ memset(head,-1,sizeof head); tol=0; memset(vis,0,sizeof vis); memset(visl,0,sizeof visl); } void add_edge(int u,int v){ E[tol].v=v; E[tol].next=head[u]; head[u]=tol++; } int f; void dfs(int u){ if(f)return ; for(int i = head[u]; i != -1; i = E[i].next){ int v = E[i].v; if(!visl[i]){ if(vis[v]){ f=1; return ; } vis[v]=1; visl[i]=1; if(i<(m1<<1)) visl[i^1]=1; dfs(v); vis[v]=0; visl[i]=0; if(i<(m1<<1)) visl[i^1]=0; } } } int main(){ //freopen("E:\\read.txt","r",stdin); int T; int u,v; scanf("%d",&T); while(T--){ scanf("%d %d %d", &n, &m1, &m2); Init(); for(int i = 1; i <= m1; i++){ scanf("%d %d", &u, &v); add_edge(u, v); add_edge(v, u); } for(int i = 1;i <= m2; i++){ scanf("%d %d", &u, &v); add_edge(u, v); } f=0; for(int i = 1; i <= n; i++){ vis[i]=1; dfs(i); vis[i]=0; if(f)break; } if(f) puts("YES"); else puts("NO"); } return 0; }