2-SAT问题
对于这类问题,我们一般的解决方案是把它抽象成一个图(如下)。这个图有
例题:[JSOI2010]满汉全席
思路:
每个厨师的两样喜好菜品可以看做一个约束条件,对于这两样菜品,如果其中一种食材已经被做成了另一样菜,那么剩下的这种食材就只能做这种菜。可以设汉式为0,满式为1,建图跑
代码:
#include<bits/stdc++.h>
#define MAXN 110
#define MAXM 1010
using namespace std;
int k,n,m,ans;
string s;
struct png
{
int met[3],hm[3];
}p[MAXM];
struct edge
{
int to,nxt;
}ed[MAXM<<1];
int head[MAXN<<1],tt=0;
void add(int u,int v)
{
ed[++tt].to=v;
ed[tt].nxt=head[u];
head[u]=tt;
}
int dfn[MAXN<<1],low[MAXN<<1],tot=0;
stack<int>arr;
int co[MAXN<<1],col=0;
void tarjan(int st)
{
dfn[st]=low[st]=++tot;
arr.push(st);
for(int i=head[st];i;i=ed[i].nxt)
{
int v=ed[i].to;
if(!dfn[v])
{
tarjan(v);
low[st]=min(low[st],low[v]);
}
else if(!co[v])low[st]=min(low[st],dfn[v]);
}
if(low[st]==dfn[st])
{
co[st]=++col;
while(!arr.empty()&&arr.top()!=st)
{
co[arr.top()]=col;
arr.pop();
}
arr.pop();
}
}
int num(string ss)
{
int ret=0;
for(int i=1;i<ss.length();i++)
ret=ret*10+(s[i]-'0');
return ret;
}
int main()
{
scanf("%d",&k);
while(k--)
{
scanf("%d%d",&n,&m);
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(co,0,sizeof(co));
memset(ed,0,sizeof(ed));
memset(head,0,sizeof(head));
tt=tot=col=0;
while(!arr.empty())arr.pop();
for(int i=1;i<=m;i++)
{
for(int j=1;j<=2;j++)
{
cin>>s;
if(s[0]=='h')p[i].hm[j]=0;
else p[i].hm[j]=1;
p[i].met[j]=num(s);
}
add(p[i].met[1]+(!p[i].hm[1])*n,p[i].met[2]+p[i].hm[2]*n);
add(p[i].met[2]+(!p[i].hm[2])*n,p[i].met[1]+p[i].hm[1]*n);
}
for(int i=1;i<=n;i++)
if(!dfn[i])
tarjan(i);
bool flag=0;
for(int i=1;i<=n;i++)
if(co[i]==co[i+n])flag=1;
if(!flag)printf("GOOD\n");
else printf("BAD\n");
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】