中文题。
思路:
两种: 一种是kuangbin的两层dfs写法(我竟然wa了之后怀疑bin神板子。。T_T,最后发现自己智障点写错了)。没毛病,可以套。。
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<iostream>
#include<math.h>
using namespace std;
const int maxn=1000005;
struct node
{
int v,next;
} edge[maxn],edgef[maxn];
int head[maxn];
int headf[maxn];
int tot1,tot2;
int vis1[maxn],vis2[maxn];
int belong[maxn];
int T[maxn];
int Bcnt,Tcnt;
void add(int u,int v)
{
edge[++tot1].v=v;
edge[tot1].next=head[u];
head[u]=tot1;
edgef[++tot2].v=u;
edgef[tot2].next=headf[v];
headf[v]=tot2;
}
void init()
{
memset(head,-1,sizeof(head));
memset(headf,-1,sizeof(headf));
memset(vis1,0,sizeof(vis1));
memset(vis2,0,sizeof(vis2));
tot1=tot2=0;
Bcnt=Tcnt=0;
}
void dfs1(int u) //正向图 dfs ,算结束时间
{
vis1[u]=1;
for(int i=head[u]; i!=-1; i=edge[i].next)
{
int v=edge[i].v;
if(!vis1[v])
dfs1(v);
}
T[++Tcnt]=u;
}
void dfs2(int u)
{
vis2[u]=1;
belong[u]=Bcnt;
for(int i=headf[u]; i!=-1; i=edgef[i].next)
{
int v=edgef[i].v;
if(!vis2[v])
dfs2(v);
}
}
int judge(int n)
{
for(int i=0; i<2*n; i++)
{
if(!vis1[i])
dfs1(i);
}
for(int i=Tcnt; i>=1; i--)
{
if(!vis2[T[i]])
{
Bcnt++;
dfs2(T[i]);
}
}
for(int i=0; i<=2*n-2; i+=2)
{
if(belong[i]==belong[i+1])
return 0;
}
return 1;
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
for(int i=0; i<m; i++)
{
int a,b,c,d;
scanf("%d%d%d%d",&a,&b,&c,&d);
int u=2*a+c,v=2*b+d;
add(u,v^1);
add(v,u^1);
}
if(judge(n))
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
第二种是正常的tarjan求强连通
//#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn=1000005;
struct Edge
{
int to,next;
} edge[maxn];
int head[maxn],tot;
int Low[maxn],DFN[maxn],Stack[maxn],Belong[maxn];
int Index,top;
int scc;
const int inf=0x3f3f3f3f;
bool Instack[maxn];
void addedge(int u,int v)
{
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
}
void Tarjan(int u)
{
int v;
Low[u] = DFN[u] = ++Index;
Stack[top++] = u;
Instack[u] = true;
for(int i = head[u]; i != -1; i = edge[i].next)
{
v = edge[i].to;
if(!DFN[v])
{
Tarjan(v);
if(Low[u] > Low[v])
Low[u] = Low[v];
}
else if(Instack[v] && Low[u] > DFN[v])
Low[u] = DFN[v];
}
if(Low[u] == DFN[u])
{
scc++;
do
{
v = Stack[--top];
Belong[v] = scc;
Instack[v] = false;
}
while( v!= u );
}
}
int main()
{
int n,m;
while(scanf("%d",&n)!=EOF)
{
int a,b,c,d;
memset(DFN,0,sizeof(DFN));
memset(Instack,false,sizeof(Instack));
Index = scc = top = tot=0;
memset(edge,0,sizeof(edge));
memset(head,-1,sizeof(head));
scanf("%d",&m);
for(int i=0; i<m; ++i)
{
scanf("%d%d%d%d",&a,&b,&c,&d);
a=(a<<1)+c;
b=(b<<1)+d;
addedge(a,b^1);
addedge(b,a^1);
}
for(int i=0; i<n<<1; ++i)
if(!DFN[i])
Tarjan(i);
int flag=0;
for(int i=0; i<n; ++i)
{
if(Belong[i<<1]==Belong[(i<<1)^1])
flag=1;
}
if(flag)printf("NO\n");
else printf("YES\n");
}
return 0;
}