hdu 3062 2-sat 水题

2-sat入门题,建图后直接模板就好了

开始的时候竟然连了双向的边,晕。。。。。

 

#include<stdio.h>

#include<string.h>

#include<vector>

#include<algorithm>

using namespace std;

const int MAX = 10010;

vector<int> edge[MAX];

int st[MAX];

int dfn[MAX],low[MAX];

int top,btype,tdfn;//btype:连通块的个数

int belong[MAX];//点属于哪个连通块

bool ins[MAX];

void dfs(int s)

{

	int i,t;

	dfn[s]=low[s]=++tdfn;

	ins[s]=true;

	st[++top]=s;

	for(i=0;i<edge[s].size();i++)

	{

		t=edge[s][i];

		if(!dfn[t])

		{

			dfs(t);

			if(low[t]<low[s]) low[s]=low[t];

		}

		else if(ins[t] && dfn[t]<low[s])  low[s]=dfn[t];

	}

	if(dfn[s]==low[s])

	{

		btype++;

		do

		{

			t=st[top--];

			ins[t]=false;

			belong[t]=btype;

		}while(t!=s);

	}

}

void SCC(int n)

{

	int i;

	top=btype=tdfn=0;

	memset(ins,false,sizeof(ins));

	memset(dfn,0,sizeof(dfn));

	for(i=1;i<=n;i++)

		if(!dfn[i])

			dfs(i);

}

int main()

{

    int i,j,k;

	int n,m;

	int a,b,c,d;

	while(scanf("%d%d",&n,&m)!=EOF)

	{

		for(i=0;i<=2*n;i++)

			edge[i].clear();

		for(i=0;i<m;i++)

		{

			scanf("%d%d%d%d",&a,&b,&c,&d);

			a++,b++;

			if(c==1&&d==1)

			{

			edge[a+n].push_back(b);

			edge[b+n].push_back(a);

			}

			if(c==0&&d==0)

			{

				edge[a].push_back(b+n);

				edge[b].push_back(a+n);

			}

			if(c==1&&d==0)

			{

		         edge[a+n].push_back(b+n);

		         edge[b].push_back(a);

			}

			if(c==0&&d==1)

			{

			   edge[a].push_back(b);

			   edge[b+n].push_back(a+n);	

			}

		}

		SCC(2*n);

		int flag=1;

		for(i=1;i<=n;i++)

		     if(belong[i]==belong[i+n])

		       flag=0;

                 if(!flag) printf("NO\n");

                 else      printf("YES\n");

	}

	return 0;

}

 

你可能感兴趣的:(HDU)