Party
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4580 Accepted Submission(s): 1508
Problem Description
有n对夫妻被邀请参加一个聚会,因为场地的问题,每对夫妻中只有1人可以列席。在2n 个人中,某些人之间有着很大的矛盾(当然夫妻之间是没有矛盾的),有矛盾的2个人是不会同时出现在聚会上的。有没有可能会有n 个人同时列席?
Input
n: 表示有n对夫妻被邀请 (n<= 1000)
m: 表示有m 对矛盾关系 ( m < (n - 1) * (n -1))
在接下来的m行中,每行会有4个数字,分别是 A1,A2,C1,C2
A1,A2分别表示是夫妻的编号
C1,C2 表示是妻子还是丈夫 ,0表示妻子 ,1是丈夫
夫妻编号从 0 到 n -1
m: 表示有m 对矛盾关系 ( m < (n - 1) * (n -1))
在接下来的m行中,每行会有4个数字,分别是 A1,A2,C1,C2
A1,A2分别表示是夫妻的编号
C1,C2 表示是妻子还是丈夫 ,0表示妻子 ,1是丈夫
夫妻编号从 0 到 n -1
Output
如果存在一种情况 则输出YES
否则输出 NO
否则输出 NO
Sample Input
2 1 0 1 1 1
Sample Output
YES
Source
Recommend
ac代码
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define max(a,b) (a>b?a:b)
#define min(a,b) (a>b?b:a)
int belong[101000],dfn[101000],low[101000],head[101000],ins[101000],stack[101000];
int cnt,taj,time,top;
int n,m;
struct s
{
int u,v,next;
}edge[1010*2*200];
void init()
{
cnt=taj=time=0;
memset(head,-1,sizeof(head));
memset(low,-1,sizeof(low));
memset(dfn,-1,sizeof(dfn));
memset(ins,0,sizeof(ins));
memset(belong,-1,sizeof(belong));
}
void addedge(int u,int v)
{
edge[cnt].u=u;
edge[cnt].v=v;
edge[cnt].next=head[u];
head[u]=cnt++;
}
void add(int a,int b,int c,int d)
{
if(c==0&&d==0)
{
addedge(a<<1,(b<<1)+1);
addedge(b<<1,(a<<1)+1);
}
else
if(c==0&&d==1)
{
addedge(a<<1,b<<1);
addedge((b<<1)+1,(a<<1)+1);
}
else
if(c==1&&d==0)
{
addedge((a<<1)+1,(b<<1)+1);
addedge(b<<1,a<<1);
}
else
if(c==1&&d==1)
{
addedge((a<<1)+1,b<<1);
addedge((b<<1)+1,a<<1);
}
}
void tarjan(int u)
{
dfn[u]=low[u]=time++;
ins[u]=1;
stack[top++]=u;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(dfn[v]==-1)
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else
if(ins[v])
{
low[u]=min(dfn[v],low[u]);
}
}
if(dfn[u]==low[u])
{
taj++;
int now;
do
{
now=stack[--top];
belong[now]=taj;
ins[now]=0;
}while(now!=u);
}
}
int _2sat()
{
int i;
for(i=0;i<2*n;i++)
{
if(dfn[i]==-1)
tarjan(i);
}
for(i=0;i<n;i++)
{
if(belong[2*i]==belong[(2*i)+1])
return 0;
}
return 1;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
int i;
init();
for(i=0;i<m;i++)
{
int a,b,c,d;
scanf("%d%d%d%d",&a,&b,&c,&d);
add(a,b,c,d);
}
if(_2sat())
printf("YES\n");
else
printf("NO\n");
}
}