hdu1824

/*
分析:
    2-SAT基础题。
    哦也,菜鸟第二道2-SAT~。
    对于每个人,要么回家、要么不回家,所以:拆点~,将一个人
活生生、血淋淋的-、-I拆成俩,既出现了a和!a。
    然后说说建边的事儿:
        队长和队员应该是:!a->b,!a->c  !b->a,!c->a
        每一个关系对里面:a->!b,b->!a
        同时,要把一个队伍里面的两队员建立b->c、c->b以及!b->
    !a、!a->!b的边(但是,事实上,这四条边即使不建立了,同样
    ac,不着为啥。是数据弱,还是前面的思路已经涵盖这个了,暂
    时牟想通0.0,欢迎懂的牛牛留言~)


                                                            2012-11-27
*/










#include"stdio.h"
#include"string.h"
#include"stdlib.h"
#include"stack"
#define N 1011
#define M 20011
using namespace std;

int n,m;

int s_index,cnt;
int DFN[6*N],LOW[6*N];
int instack[6*N],belong[6*N];

struct Eage{
	int from,to,next;
}eage[M];
int tot,head[6*N];
void add(int a,int b){
	eage[tot].from=a;eage[tot].to=b;eage[tot].next=head[a];head[a]=tot++;
}

void get_map()
{
	int i;
	int a,b,c;
	int base=3*n;
	tot=0;
	memset(head,-1,sizeof(head));
	for(i=0;i<n;i++)
	{
		scanf("%d%d%d",&a,&b,&c);
		add(b,c);add(c,b);
		add(b+base,c+base);add(c+base,b+base);
		add(a+base,b);
		add(a+base,c);
		add(b+base,a);
		add(c+base,a);
	}
	while(m--)
	{
		scanf("%d%d",&a,&b);
		add(a,b+base);
		add(b,a+base);
	}
}
stack<int>st;
void DFS(int k)
{
	int j,v;
	st.push(k);
	instack[k]=1;
	DFN[k]=LOW[k]=++s_index;
	for(j=head[k];j!=-1;j=eage[j].next)
	{
		v=eage[j].to;
		if(instack[v])	LOW[k]=LOW[k]>DFN[v]?DFN[v]:LOW[k];
		else if(DFN[v]==-1)
		{
			DFS(v);
			LOW[k]=LOW[k]>LOW[v]?LOW[v]:LOW[k];
		}
	}
	if(DFN[k]==LOW[k])
	{
		do
		{
			j=st.top();
			st.pop();
			instack[j]=0;
			belong[j]=cnt;
		}while(j!=k);
		cnt++;
	}
}
void Tarjan()
{
	int i,t;
	cnt=s_index=0;
	memset(DFN,-1,sizeof(DFN));
	memset(LOW,-1,sizeof(LOW));
	memset(belong,-1,sizeof(belong));
	memset(instack,0,sizeof(instack));
	for(i=0,t=6*n;i<t;i++)	if(DFN[i]==-1)	DFS(i);
}
int Judge()
{
	int i;
	int t=3*n;
	for(i=0;i<t;i++)	if(belong[i]==belong[i+t])	return 1;
	return 0;
}
int main()
{
	while(scanf("%d%d",&n,&m)!=-1)
	{
		get_map();
		Tarjan();
		if(Judge())	printf("no\n");
		else		printf("yes\n");
	}
	return 0;
}


你可能感兴趣的:(hdu1824)