题目链接:点击打开链接
思路:根据不相容的集合组成有向图,然后在有向图中找极大连通子图,如果夫妻两个在同一个连通中,则无解。代码:
#include<iostream>
#include <vector>
#include <stack>
using namespace std;
const int N=2005;
int dfn[N],low[N],ins[N],gin[N];
vector<int> gra[N];
stack<int> sta;
int n,m;
int index,id;
void re() {
memset(gra,0,sizeof(gra));
for(int i=0;i<2*n;++i)
gra[i].clear();
int a1,a2,b1,b2;
for(int i=0; i<m; ++i) {
scanf("%d%d%d%d",&a1,&a2,&b1,&b2);
int k=2*a1+b1,u=2*a2+b2;
gra[k].push_back(u^1);
gra[u].push_back(k^1);
}
}
void tarjan(int u){
dfn[u]=low[u]=++index;
sta.push(u);
ins[u]=1;
for(size_t i=0;i<gra[u].size();++i){
int v=gra[u][i];
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}else if(ins[v]){
low[u]=min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u]){
++id;
while(!sta.empty()){
int s=sta.top();
sta.pop();
gin[s]=id;
ins[s]=0;
if(u==s) break;
}
}
}
void run() {
while(!sta.empty()){
sta.pop();
}
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(ins,0,sizeof(ins));
index=0;id=0;
for(int i=0;i<2*n;++i){
if(!dfn[i]){
tarjan(i);
}
}
bool flag=false;
for(int i=0;i<2*n;i+=2){
if(gin[i]==gin[i^1]){
flag=true;
break;
}
}
if(flag) cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}
int main() {
//#ifndef ONLINE_JUDGE
// freopen("in.txt","r",stdin);
//#endif
while(scanf("%d%d",&n,&m)==2) {
re();
run();
}
return 0;
}