Party

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 5247    Accepted Submission(s): 1695

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
 
Output
如果存在一种情况 则输出YES

否则输出 NO
 
Sample Input
2
1
0 1 1 1
 
Sample Output
YES
 
Source
2009 Multi-University Training Contest 16 - Host by NIT

/*2-sat建图有点麻烦,每次要考虑很多,刚学,好多不懂,对于这道题,
有两种矛盾关系一是夫妻之间不能同时去,二是有矛盾的两个人不能同时
在场,所以先根据夫妻建边,然后根据具体的矛盾关系建边*/
#include<stdio.h>
#include<string.h>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;
#define MAX 100000+10
int low[MAX],dfn[MAX];
int head[MAX],sccno[MAX];
int scc_cnt,dfs_clock,cnt,m,n;
stack<int>s;
bool Instack[MAX];
struct node
{
int u,v;
int next;
}edge[MAX*2];
void init()
{
cnt=0;
memset(head,-1,sizeof(head));
}
void add(int u,int v)
{
edge[cnt].u=u;
edge[cnt].v=v;
edge[cnt].next=head[u];
head[u]=cnt++;
}
void getmap()
{//一对夫妻只能去一个人,所以分别建边,以为只有男女之分,所以4层就够了
for(int i=0;i<n;i++)
{
add(i+3*n,i);
add(i+2*n,i+n);
add(i+n,i+2*n);
add(i,i+3*n);
}
int a1,a2,c1,c2;
while(m--)
{//按照矛盾关系建边,女在偶数层,男在奇数层,第一组与第二组也有一些分别
scanf("%d%d%d%d",&a1,&a2,&c1,&c2);
if(c1==0&&c2==0)
//四种关系0--0 1--1 1--0 0--1
{
add(a1,a2+2*n);
add(a2,a1+2*n);
}
else if(c1==1&&c2==1)
{
add(a1+n,a2+3*n);
add(a2+n,a1+3*n);
}
else if(c1==1&&c2==0)
{
add(a1+n,a2+2*n);
add(a2,a1+3*n);
}
else
{
add(a1,a2+3*n);
add(a2+n,a1+2*n);
}
}
}
void tarjan(int u,int fa)
{
int v;
low[u]=dfn[u]=++dfs_clock;
s.push(u);
Instack[u]=true;
for(int i=head[u];i!=-1;i=edge[i].next)
{
v=edge[i].v;
if(!dfn[v])
{
tarjan(v,u);
low[u]=min(low[u],low[v]);
}
else if(Instack[v])
low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u])
{
scc_cnt++;
for(;;)
{
v=s.top();
s.pop();
Instack[v]=false;
sccno[v]=scc_cnt;
if(v==u) break;
}
}
}
void find(int l,int r)
{
memset(sccno,0,sizeof(sccno));
memset(Instack,false,sizeof(Instack));
memset(low,0,sizeof(low));
memset(dfn,0,sizeof(dfn));
scc_cnt=dfs_clock=0;
for(int i=l;i<=r;i++)
if(!dfn[i])
tarjan(i,-1);
}
void solve()
{
int flog=1;
for(int i=0;i<2*n;i++)
{
if(sccno[i]==sccno[i+2*n])//如果有矛盾的两个人在一组
{
flog=0;
printf("NO\n");
break;
}
}
if(flog)
printf("YES\n");
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
getmap();
find(0,4*n-1);
solve();
}
return 0;
}

最新文章

  1. codecademy-command line_filesystem
  2. DFS &amp; BFS
  3. ECharts2.2.0 兼容IE8
  4. [MEAN Stack] First API -- 1. with Node.js, Express and MongoDB
  5. mac OS X下安装Redis及Thinkphp3.1使用Redis
  6. Java [Leetcode 231]Power of Two
  7. js的new操作符
  8. canvas个人总结
  9. 汇编指令-bic(位清除)、orr(位或)(3)
  10. MySQL数据库规约.
  11. Linux学习之CentOS(十六)-----内存置换空间(swap)之建置(转)
  12. AccessTokenValidation3 源码分析 jwttoken验证流程图
  13. C#-类(九)
  14. IIS小知识
  15. 搜藏一个php文件上传类
  16. ubuntu 14.04 上配置vlc组播源
  17. 导出putty配置
  18. hive列转行
  19. 【Hadoop 分布式部署 二:分布式环境预备工作(主机名 IP地址等设置)】
  20. ABAP--如何创建自定义打印条码

热门文章

  1. sql server 创建索引 超时时间已到
  2. jquery自动完成插件的使用
  3. DB2大数据量优化查询解决方案
  4. 「Redis 笔记」常用命令
  5. 组装自己的tesla超级计算机
  6. socket 的通信过程
  7. 优动漫PAINT用户界面介绍
  8. PHP 判断一个字符是否在字符串中
  9. 利用UNIX时间戳来计算ASP的在线时间
  10. Bash 如何取得当前正在执行的脚本的绝对路径?