#include<bits/stdc++.h>
using namespace std;
const int maxn=2005;
int a,b,c,d,n,m,num,head[2][maxn];
int q[maxn],vis[maxn],f[maxn],cnt[2];
struct ss{
int v,nex;
}g[2][maxn*maxn];
//+n表示丈夫
//关于建边:表示u,v同时存在
void creat(int u,int v){
g[0][++cnt[0]]={v,head[0][u]};head[0][u]=cnt[0];
g[1][++cnt[1]]={u,head[1][v]};head[1][v]=cnt[1];
}
//0是原图,1是反图
void dfs1(int u){
vis[u]=1;//每次dfs的开始就会改vis,所以后面if里不用再写了
for(int i=head[0][u];i;i=g[0][i].nex){
//i是下标!!g[0][i].v才是邻接点
int v=g[0][i].v;
if(!vis[v]) dfs1(v);
}
q[num++]=u;
}
void dfs2(int x,int y){
vis[x]=0;f[x]=y;
for(int i=head[1][x];i;i=g[1][i].nex){
int v=g[1][i].v;
if(vis[v]) dfs2(v,y);
}
}
//只是遍历反图,按什么顺序在主函数中实现
int main(){
while(cin>>n>>m){
memset(vis,0,sizeof(vis));//dfs1原图vis初始为0.反图的初始为1
memset(head,0,sizeof(head));
cnt[0]=cnt[1]=0;
for(int i=0;i<m;i++){
scanf("%d%d%d%d",&a,&b,&c,&d);
//ac和bd有矛盾,所以其中一家得换一个人即1-x
creat(a+c*n,b+(1-d)*n);
creat(b+d*n,a+(1-c)*n);
}
num=0;
for(int i=0;i<2*n;i++){//2倍别忘了 !!!
if(!vis[i]) dfs1(i);
}
for(int i=2*n-1;i>=0;i--){ //0~n-1和n~2*n-1。所以不是2*(n-1)
if(vis[q[i]]) dfs2(q[i],q[i]);
}
//一对夫妻只有一人去 的矛盾关系通过判断是否为强连通分量来实现
int ans=1;
for(int i=0;i<n;i++){
if(f[i]==f[i+n]){
ans=0;break;
//若一对夫妻在同一个强连通分量里就不行,因为一对夫妻只能去一个
}
}
if(ans) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
//0~n-1对
09-14
373
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)
07-12
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交