题意:很标准的求是否满足2-SAT
解法:两个人之间互相厌恶 那么我们建图的时候只需要建立i->j i^1-j^1 或者相反就可以了
留个不是tarjan的模板
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<vector>
#include<algorithm>
using namespace std;
#define maxn 20010
int n,m; //顶点数
vector<int>rg[maxn];
vector<int>g[maxn];
vector<int>vs; //后序遍历顺序的顶点列表
bool vis[maxn];
int scin[maxn],scout[maxn];
int cmp[maxn]; //所属强联通分量的拓扑序
void add(int from,int to){
g[from].push_back(to);
rg[to].push_back(from);
}
void dfs(int v){
vis[v]=1;
for(int i=0;i<g[v].size();++i){
if(!vis[g[v][i]])dfs(g[v][i]);
}
vs.push_back(v);
}
void rdfs(int v,int k){
vis[v]=1;
cmp[v]=k;
for(int i=0;i<rg[v].size();++i){
if(!vis[rg[v][i]]){rdfs(rg[v][i],k);}
}
}
int scc()
{
memset(vis,0,sizeof vis);
memset(cmp,0,sizeof cmp);
vs.clear();
for(int i=0;i<n;i++){
if(!vis[i])dfs(i);
}
memset(vis,0,sizeof vis);
int k=0;
for(int i=(int)vs.size()-1;i>=0;i--){
if(!vis[vs[i]])rdfs(vs[i],k++);
}
return k;
}
void build(){
for(int i=0;i<=n;++i){g[i].clear();rg[i].clear();}
int a,b,c,d;
for(int i=0;i<m;++i){
scanf("%d%d%d%d",&a,&b,&c,&d);
// add((a<<1)+c,(b<<1)+(1-d));
// add((b<<1)+d,(a<<1)+(1-c));
add((b<<1)+(1-d),(a<<1)+c);
add((a<<1)+(1-c),(b<<1)+d);
}
}
int judge(){
int sc=scc();
int fl=1;
for(int i=0;i<n;i+=2){
if(cmp[i]==cmp[i^1]){
fl=0;
break;
}
}
return fl;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
// if(!n&&!m)break;
n<<=1;
build();
if(judge())printf("YES\n");
else printf("NO\n");
}
return 0;
}