HDU 1824 2-SAT

 

Let's go home
Problem Description

小时候,乡愁是一枚小小的邮票,我在这头,母亲在那头。
                        —— 余光中

集训是辛苦的,道路是坎坷的,休息还是必须的。经过一段时间的训练,lcy决定让大家回家放松一下,但是训练还是得照常进行,lcy想出了如下回家规定,每一个队(三人一队)或者队长留下或者其余两名队员同时留下;每一对队员,如果队员A留下,则队员B必须回家休息下,或者B留下,A回家。由于今年集训队人数突破往年同期最高记录,管理难度相当大,lcy也不知道自己的决定是否可行,所以这个难题就交给你了,呵呵,好处嘛~,免费**漂流一日。
 

Input
第一行有两个整数,T和M,1<=T<=1000表示队伍数,1<=M<=5000表示对数。
接下来有T行,每行三个整数,表示一个队的队员编号,第一个队员就是该队队长。
然后有M行,每行两个整数,表示一对队员的编号。
每个队员只属于一个队。队员编号从0开始。
 

Output
可行输出yes,否则输出no,以EOF为结束。
 

Sample Input
1 2 0 1 2 0 1 1 2 2 4 0 1 2 3 4 5 0 3 0 4 1 3 1 4
 

Sample Output
yes no


题意:不解释。

思路:根据题中所给冲突关系建图,tarjin缩点,判断存在有冲突关系的点是否在同一个连通分量里,假设存在,则方案不成立,否则成立。

代码:

 

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<math.h>
#include<vector>
using namespace std;
struct node
{
         int next,to;
}edge[5000000];
int head[50000],stk[1000000],belong[50000],dfn[50100],top,scc,indexx,T[50100],tol,low[50050];
bool instack[1010];
void add(int u,int v)
{
         edge[tol].to=v;
         edge[tol].next=head[u];
         head[u]=tol++;
}
void tarjin(int u)
{
         low[u]=dfn[u]=++indexx;
         stk[top++]=u;
         instack[u]=1;
         int i,v;
         for(i=head[u];i!=-1;i=edge[i].next)
         {
                  v=edge[i].to;
                  if(!dfn[v])
                  {
                           tarjin(v);
                           if(low[u]>low[v])low[u]=low[v];
                  }
                  if(instack[v]&&low[u]>dfn[v])low[u]=dfn[v];
         }
         if(low[u]==dfn[u])
         {
                  scc++;
                  do
                  {
                           v=stk[--top];
                           instack[v]=0;
                           belong[v]=scc;
                  }while(v!=u);
         }
}
bool solve(int n)
{
         memset(dfn,0,sizeof(dfn));
         memset(instack,0,sizeof(instack));
         indexx=top=scc=0;
         int i,v,u;
         for(i=0;i<6*n;i++)if(!dfn[i])tarjin(i);

}
int main()
{
         int i,j,k,m,n,p,q;
         while(~scanf("%d%d",&n,&m))
         {
                 memset(head,-1,sizeof(head));
                 tol=0;
                 for(p=0;p<n;p++)
                 {
                          scanf("%d%d%d",&i,&j,&k);
                          add(2*i+1,2*j);
                          add(2*i+1,2*k);
                          add(2*j+1,2*i);
                          add(2*k+1,2*i);
                 }
                 while(m--)
                 {
                          scanf("%d%d",&i,&j);
                          add(2*i,2*j+1);
                          add(2*j,2*i+1);
                 }
                 solve(n);
                 bool flag=1;
                 for(i=0;i<n;i++)
                  if(belong[2*i]==belong[2*i+1])flag=0;
                 if(flag)puts("yes");else puts("no");
         }
         return 0;
}

 

posted @ 2013-09-03 00:27  线性无关  阅读(123)  评论(0)    收藏  举报