hdu 3062

时间:2023-03-08 21:49:18
hdu 3062

2-SAT的入门题;

网上说这个算法最好的入门教材是:伍昱的《由对称性解2-SAT问题》的ppt和赵爽的论文《2-SAT 解法浅析》;

看了一下伍昱的ppt,很好理解!

而这道题相对ppt里面的例子来说更加简单;

代码:

 #include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cstring>
#define maxn 2010
using namespace std; vector<int>ve[maxn];
stack<int>s;
int low[maxn],dfn[maxn],b[maxn],nncount,cnt;
bool instack[maxn]; void tarjin(int u)
{
low[u]=dfn[u]=++nncount;
s.push(u);
instack[u]=;
int l=ve[u].size();
for(int i=;i<l;i++)
{
int v=ve[u][i];
if(!dfn[v])
{
tarjin(v);
low[u]=min(low[u],low[v]);
}
else if(instack[v])
low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u])
{
cnt++;
int v;
do
{
v=s.top();
s.pop();
b[v]=cnt;
instack[v]=;
}while(v!=u);
}
} int main()
{
int n,m,x,y,u,v;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=;i<*n;i++)
ve[i].clear();
memset(low,,sizeof low);
memset(dfn,,sizeof dfn);
memset(b,,sizeof b);
nncount=cnt=;
for(int i=;i<m;i++)
{
scanf("%d%d%d%d",&x,&y,&u,&v);
ve[(x<<)+u].push_back((y<<|)-v);
ve[(y<<)+v].push_back((x<<|)-u);
}
bool flag=;
for(int i=;i<*n;i++)
if(!dfn[i]) tarjin(i);
for(int i=;i<n;i++)
if(b[i<<]==b[i<<|]) {flag=;break;}
if(flag) puts("NO");
else puts("YES");
}
return ;
}