2-SAT
Before
一般形式为
模型
有若干个包含2个元素的集合,只能选择每个集合中的一个元素,并给出一些条件(例:选a后不能选b),要求求出满足这些条件的选择,这个解也称为
A B C
A' B' C'
若给出条件,{A,B'} , {B'C'} 不能同时选择
因为 {A,A'} , {B,B'} , {C,C'} 中,每个集合都要选出一个元素,即不能同时选择
又因为 {A,B'} 不能同时选择,则选择B'时,一定选择A',于是在 B',A' 之间连上一条有向边(因选 A' 不一定 B');同理,在选 B 时也一定选 A
于是可以建图
集合内元素是否矛盾就是
有,则不存在解
输出方案时可以通过变量在图中的拓扑序确定该变量的取值
我们可以发现,缩点后强连通分量的编号就是反着的拓扑排序
时间复杂度
非常的板,精髓在灵活建图
int head[N],nxt[N],to[N],tot=0;
int dfn[N],low[N],cnt=0;
int st[N],vis[N],pot[N],d[N],p[N],tp;
int n,m,t=0;
void add(int u,int v) {
nxt[++tot]=head[u];
to[tot]=v;
head[u]=tot;
}
void Tarjan(int u) {
low[u]=dfn[u]=++t;
st[++tp]=u;
vis[u]=1;
for(int i=head[u];i;i=nxt[i]) {
int v=to[i];
if(!dfn[v]) {
Tarjan(v);
low[u]=min(low[u],low[v]);
} else if(vis[v]) {
low[u]=min(low[u],low[v]);
}
}
if(dfn[u]==low[u]) {
int v;
cnt++;
while(v=st[tp--]) {
pot[v]=u;
vis[v]=0;
d[v]=cnt;
if(u==v) break;
}
}
}
bool fl=1;
signed main() {
n=read();
m=read();
for(int i=1;i<=m;i++) {
int u=read(),iu=read(),v=read(),iv=read();
add(u+(iu^1)*n,v+iv*n);//建图,以题意为准灵活更改
add(v+(iv^1)*n,u+iu*n);
}
for(int i=1;i<=n*2;i++) {
if(!dfn[i]) Tarjan(i);
}
//...与d数组相关...
return 0;
}
满汉全席
https://www.luogu.com.cn/problem/P4171
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=8e3+100;
int read() {
int x=0,f=1;
char ch=getchar();
while(ch<48||ch>57) {
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>=48&&ch<=57) {
x=(x<<3)+(x<<1)+(ch^48);
ch=getchar();
}
return x*f;
}
int head[N],nxt[N],to[N],tot=0;
int dfn[N],low[N],cnt=0;
int st[N],vis[N],d[N],p[N],tp;
int n,m,t=0;
void add(int u,int v) {
nxt[++tot]=head[u];
to[tot]=v;
head[u]=tot;
}
void Tarjan(int u) {
low[u]=dfn[u]=++t;
st[++tp]=u;
vis[u]=1;
for(int i=head[u]; i; i=nxt[i]) {
int v=to[i];
if(!dfn[v]) {
Tarjan(v);
low[u]=min(low[u],low[v]);
} else if(vis[v]) {
low[u]=min(low[u],low[v]);
}
}
if(dfn[u]==low[u]) {
int v;
cnt++;
while(v=st[tp--]) {
vis[v]=0;
d[v]=cnt;
if(u==v) break;
}
}
}
bool fl=1;
void init() {
tp=0;
cnt=0;
tot=0;
fl=1;
memset(head,0,sizeof(head));
memset(vis,0,sizeof(vis));
memset(d,0,sizeof(d));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
}
int get_num(string s) {
int tt=1,o=0,len=s.length();
while(s[tt]>=48&&s[tt]<=57&&tt<len) o=o*10+s[tt]-48,tt++;
return o;
}
int T;
string s1,s2;
signed main() {
T=read();
while(T--) {
n=read();
m=read();
init();
for(int i=1; i<=m; i++) {
cin>>s1>>s2;
int u=get_num(s1);
int v=get_num(s2);
if(s1[0]=='m') {
if(s2[0]=='m') add(u+n,v),add(v+n,u);
if(s2[0]=='h') add(u+n,v+n),add(v,u);
}
if(s1[0]=='h') {
if(s2[0]=='m') add(u,v),add(v+n,u+n);
if(s2[0]=='h') add(u,v+n),add(v,u+n);
}
}
for(int i=1; i<=n*2; i++) {
if(!dfn[i]) Tarjan(i);
}
for(int i=1;i<=n;i++) {
if(d[i]==d[i+n]) {
fl=0;
break;
}
}
if(!fl) printf("BAD\n");
else printf("GOOD\n");
}
return 0;
}
[POI2001] 和平委员会
https://www.luogu.com.cn/problem/P5782
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=3e6+10;
const int inf=1e9;
int read() {
int x=0,f=1;
char ch=getchar();
while(ch<48||ch>57) {
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>=48&&ch<=57) {
x=(x<<3)+(x<<1)+(ch^48);
ch=getchar();
}
return x*f;
}
int head[N],nxt[N],to[N],tot=0;
int dfn[N],low[N],cnt=0;
int st[N],vis[N],pot[N],d[N],p[N],tp;
int n,m,t=0;
void add(int u,int v) {
nxt[++tot]=head[u];
to[tot]=v;
head[u]=tot;
}
int partner(int x) {
if(x&1) return x+1;
else return x-1;
}
void Tarjan(int u) {
low[u]=dfn[u]=++t;
st[++tp]=u;
vis[u]=1;
for(int i=head[u];i;i=nxt[i]) {
int v=to[i];
if(!dfn[v]) {
Tarjan(v);
low[u]=min(low[u],low[v]);
} else if(vis[v]) {
low[u]=min(low[u],low[v]);
}
}
if(dfn[u]==low[u]) {
int v;
cnt++;
while(v=st[tp--]) {
pot[v]=u;
vis[v]=0;
d[v]=cnt;
if(u==v) break;
}
}
}
bool fl=1;
signed main() {
n=read();
m=read();
for(int i=1;i<=m;i++) {
int u=read(),v=read();
add(u,partner(v));
add(v,partner(u));
}
for(int i=1;i<=n*2;i++) {
if(!dfn[i]) Tarjan(i);
}
for(int i=1;i<=n*2;i++) {
if(d[i]==d[partner(i)]) fl=0;
}
if(!fl) printf("NIE\n");
else {
for(int i=1;i<=n*2;i++) {
if(d[i]<d[partner(i)]) printf("%lld\n",i);
}
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具