POJ 3678

2-SAT 问题板子题,怎么建边见代码

#include<bits/stdc++.h>
using namespace std;
#define N 2100
#define M 1000005

int head[N],dfn[N],low[N],id[N];
int n,m,cnt,scnt;
stack<int>st;
struct node{
int to,next;
}edge[M*7];

void addedge(int u,int v,int k)
{
edge[k].to=v;
edge[k].next=head[u];
head[u]=k;
}

void tarjan(int u)
{
int v,i,min1=dfn[u]=low[u]=cnt++;
st.push(u);
for(i=head[u];i!=-1;i=edge[i].next)
{
v=edge[i].to;
if(dfn[v]==-1)tarjan(v);
min1=min(min1,low[v]);
}
if(min1<low[u]){low[u]=min1;return;}
do
{
id[v=st.top()]=scnt;
st.pop();
low[v]=n*2;
}while(v!=u);
scnt++;
}

void init()
{
memset(dfn,-1,sizeof(dfn));
memset(id,-1,sizeof(id));
memset(head,-1,sizeof(head));
scnt=cnt=0;
}

int main()
{
int i,j,a,b,c;
char op[4];
scanf("%d%d",&n,&m);
init();
int num=0;
for(i=0;i<m;i++)
{
scanf("%d%d%d%s",&a,&b,&c,op);
if(!strcmp(op,"AND"))
{
if(c==1)
{
addedge(a,a+n,num++);
addedge(b,b+n,num++);
addedge(a+n,b+n,num++);
addedge(b+n,a+n,num++);
}
else
{
addedge(a+n,b,num++);
addedge(b+n,a,num++);
}
}
else
if(!strcmp(op,"OR"))
{
if(c==0)
{
addedge(a+n,a,num++);
addedge(b+n,b,num++);
addedge(a,b,num++);
addedge(b,a,num++);
}
else
{
addedge(a,b+n,num++);
addedge(b,a+n,num++);
}
}
else
if(!strcmp(op,"XOR"))
{
if(c==0)
{
addedge(a,b,num++);
addedge(b,a,num++);
addedge(a+n,b+n,num++);
addedge(b+n,a+n,num++);
}
else
{
addedge(a,b+n,num++);
addedge(b+n,a,num++);
addedge(a+n,b,num++);
addedge(b,a+n,num++);
}
}
}
int flag=1;
for(i=0;i<n*2;i++)
if(dfn[i]==-1)tarjan(i);
for(i=0;i<n;i++)
{
if(id[i]==id[i+n]&&id[i]!=-1)
{
flag=0;
break;
}
}
if(flag)printf("YES\n");
else printf("NO\n");
while(!st.empty())st.pop();

return 0;

猜你喜欢

转载自www.cnblogs.com/blogoflyn/p/10902067.html
POJ
今日推荐