跟游神学了2-sat!
自己懒不写了qwq
贴个别人的博客
写的还算清晰
https://blog.csdn.net/pi9nc/article/details/11849843
然后这个题就是裸题啦
不过要注意输出字典序最小的只能用dfs不能用tarjan
qwq没看到这个写了好久
然后2-sat要用的就是构图吧
好像有几个经典构图方案?
算了不管了
贴代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 16005
#define maxm 40005
using namespace std;
int n,m,cnt,head[maxn],ans[maxn],col[maxn],tot;
bool vis[maxn];
struct EDGE{
int to,nxt;
}edge[maxm];
inline int rd(){
int x=0,f=1;char c=' ';
while(c>'9' || c<'0') {if(c=='-') f=-1;c=getchar();}
while(c<='9' && c>='0') x=x*10+c-'0',c=getchar();
return x*f;
}
void init(){
cnt=0;
memset(head,0,sizeof head);
memset(ans,0,sizeof ans);
}
void add(int x,int y){
cnt++;
edge[cnt].to=y;
edge[cnt].nxt=head[x];
head[x]=cnt;
}
bool paint(int x){
if(col[x]){
if(col[x]&1) return true;
return false;
}
col[x]=1,col[x^1]=2;
ans[++tot]=x;
for(int i=head[x];i;i=edge[i].nxt){
int y=edge[i].to;
if(!paint(y)) return false;
}
return true;
}
bool work(){
memset(col,0,sizeof col);
for(int i=0;i<2*n;i++){
if(col[i]) continue;
tot=0;
if(!paint(i)){
for(int j=1;j<=tot;j++)
col[ans[j]]=col[ans[j]^1]=0;
if(!paint(i^1)) return false;
}
}
return true;
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
init();
for(int i=1;i<=m;i++){
int x,y;
x=rd(); y=rd();
x--,y--;
add(x,y^1); add(y,x^1);
}
if(work()){
for(int i=0;i<2*n;i++)
if(col[i]==1) printf("%d\n",i+1);
}
else printf("NIE\n");
}
return 0;
}