题目链接:点击这里
代码如下:
#include <cstdio>
#include <cstring>
#include <vector>
#include<iostream>
#include <algorithm>
#define maxd 2020
using namespace std;
int n,m,tot=0;//n个点,m条边
struct node{
int to,next;
}edge[500050];
int numedge=0;//链式前向星存边用
int head[maxd],low[maxd],dfn[maxd],belong[maxd];
//belong 相同的属于同一个强连通分量 num代表强连通分量所含的点数
int scc=0,cnt=0,top=0;
int stack[maxd];
bool instack[maxd];
void addedge(int u,int v){
edge[++numedge].to=v;
edge[numedge].next=head[u];
head[u]=numedge;
}
void tarjan(int u){
//中规中矩的tarjan
stack[++top]=u;
low[u]=dfn[u]=++cnt;
instack[u]=true;
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].to;
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(instack[v]) low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u]){
++scc;
do{
instack[stack[top]]=false;
belong[stack[top]]=scc;
}while(u!=stack[top--]);
}
}
void init(){
//初始化
tot=0;
numedge=0;
scc=0,cnt=0,top=0;
memset(head,0,sizeof(head));
memset(low,0,sizeof(low));
memset(dfn,0,sizeof(dfn));
memset(belong,0,sizeof(belong));
memset(stack,0,sizeof(stack));
memset(instack,0,sizeof(instack));
}
bool solve(){
for(int i=0;i<2*n;++i){
if(!dfn[i]) tarjan(i);
}
for(int i=0;i<2*n;i+=2){
if(belong[i]==belong[i+1]) return 0;
}//丈夫和妻子不能同时出席,故如果在同一个强连通分量中,那么返回false
return 1;
}
int main() {
while(~scanf("%d%d",&n,&m)){
init();
for(int i=1;i<=m;++i){
int a1,a2,c1,c2;
scanf("%d%d%d%d",&a1,&a2,&c1,&c2);
addedge(2*a1+c1,2*a2+1-c2);
addedge(2*a2+c2,2*a1+1-c1);
}
if(solve()){
printf("YES\n");
}
else{
printf("NO\n");
}
}
return 0;
}