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
 
思路:2-SAT模版题,分别要求夫妻必上一个、仇人不能同时上
 
两个代码,第一个是普通的搜索,第二个是tarjan的解法,第一个593MS,第二个625MS(难道写挫了。。。?),(好吧用改一下第二个代码用C++交变成了312MS……)
 
 #include <cstdio>
#include <cstring>
using namespace std; const int MAXN = ;
const int MAXM = **; struct TwoSAT{
int n, ecnt;
bool mark[MAXN];
int St[MAXN], c;//手动栈
int head[MAXN];
int next[MAXM], to[MAXM]; bool dfs(int x){
if(mark[x^]) return false;
if(mark[x]) return true;
mark[x] = true;
St[c++] = x;
for(int p = head[x]; p; p = next[p])
if(!dfs(to[p])) return false;
return true;
} void init(int n){
this->n = n;
ecnt = ;
memset(head,,sizeof(head));
memset(mark,,sizeof(mark));
} void addEdge1(int x, int y){//x*y=false
to[ecnt] = y^; next[ecnt] = head[x]; head[x] = ecnt++;
to[ecnt] = x^; next[ecnt] = head[y]; head[y] = ecnt++;
} void addEdge2(int x, int y){//x+y=true
to[ecnt] = y; next[ecnt] = head[x^]; head[x^] = ecnt++;
to[ecnt] = x; next[ecnt] = head[y^]; head[y^] = ecnt++;
} bool solve(){
for(int i = ; i < n*; i += )
if(!mark[i] && !mark[i+]){
c = ;
if(!dfs(i)) {
while(c>) mark[St[--c]] = false;
if(!dfs(i^)) return false;
}
}
return true;
}
} G; int main(){
int n, m, a, b, c, d;
while(scanf("%d%d",&n,&m)!=EOF){
G.init(n);
for(int i = ; i < n; ++i) G.addEdge2(i*,(i+n)*);
while(m--){
scanf("%d%d%d%d",&a,&b,&c,&d);
G.addEdge1((a + n*c)*, (b + n*d)*);
}
if(G.solve()) printf("YES\n");
else printf("NO\n");
}
return ;
}
 #include <cstdio>
#include <cstring>
using namespace std; const int MAXN = ;
const int MAXM = **; struct TwoSAT{
int n, ecnt, dfs_clock, scc_cnt;
int St[MAXN], c;//手动栈
int head[MAXN], lowlink[MAXN], pre[MAXN], sccno[MAXN];
int next[MAXM], to[MAXM]; void dfs(int u){
pre[u] = lowlink[u] = ++dfs_clock;
St[++c] = u;
for(int p = head[u]; p; p = next[p]){
int &v = to[p];
if(!pre[v]){
dfs(v);
if(lowlink[u] > lowlink[v]) lowlink[u] = lowlink[v];
}else if(!sccno[v]){
if(lowlink[u] > pre[v]) lowlink[u] = pre[v];
}
}
if(lowlink[u] == pre[u]){
scc_cnt++;
while(true){
int x = St[c--];
sccno[x] = scc_cnt;
if(x == u) break;
}
}
} void init(int n){
this->n = n;
ecnt = ; dfs_clock = scc_cnt = ;
memset(head,,sizeof(head));
memset(sccno,,sizeof(sccno));
memset(pre,,sizeof(pre));
} void addEdge1(int x, int y){//x*y=false
to[ecnt] = y^; next[ecnt] = head[x]; head[x] = ecnt++;
to[ecnt] = x^; next[ecnt] = head[y]; head[y] = ecnt++;
} bool solve(){
for(int i = ; i < n; ++i)
if(!pre[i]) dfs(i);
for(int i = ; i < n; i += )
if(sccno[i] == sccno[i^]) return false;
return true;
}
} G; int main(){
int n, m, a, b, c, d;
while(scanf("%d%d",&n,&m)!=EOF){
G.init(*n);
while(m--){
scanf("%d%d%d%d",&a,&b,&c,&d);
G.addEdge1(a* + c, b* + d);
}
if(G.solve()) printf("YES\n");
else printf("NO\n");
}
return ;
}

tarjan

HDU 3062 Party(2-SAT模版题)的更多相关文章

  1. hdu 1213(并查集模版题)

    How Many Tables Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  2. HDU 1083 Courses(最大匹配模版题)

    题目大意: 一共有N个学生跟P门课程,一个学生可以任意选一 门或多门课,问是否达成:    1.每个学生选的都是不同的课(即不能有两个学生选同一门课)   2.每门课都有一个代表(即P门课都被成功选过 ...

  3. Go Deeper HDU - 3715(2 - sat 水题 妈的 智障)

    Go Deeper Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total S ...

  4. HDU 2222 Keywords Search(AC自动机模版题)

    Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others ...

  5. HDU 1712 ACboy needs your help (分组背包模版题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1712 有n门课,和m天时间.每门课上不同的天数有不同的价值,但是上过这门课后不能再上了,求m天里的最大 ...

  6. hdu 4825 Xor Sum(01字典树模版题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4825 题解:一到01字典树的模版题,01字典树就是就是将一些树用二进制放到一个树上这样可以方便对整体异 ...

  7. E - Just a Hook HDU - 1698 线段树区间修改区间和模版题

    题意  给出一段初始化全为1的区间  后面可以一段一段更改成 1 或 2 或3 问最后整段区间的和是多少 思路:标准线段树区间和模版题 #include<cstdio> #include& ...

  8. hdu 1286 找新朋友 欧拉函数模版题

    找新朋友 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Problem Des ...

  9. 【hdu 1576】A/B(数论--拓展欧几里德 求逆元 模版题)

    题意:给出 A%9973 和 B,求(A/B)%9973的值. 解法:拓展欧几里德求逆元.由于同余的性质只有在 * 和 + 的情况下一直成立,我们要把 /B 转化为 *B-1,也就是求逆元. 对于 B ...

随机推荐

  1. 『ACM C++』 PTA 天梯赛练习集L1 | 052-053

    今日刷题,水题水题 ------------------------------------------------L1-052------------------------------------ ...

  2. acm--1004

    问题描述 再次比赛时间!看到气球在四周漂浮,多么兴奋.但要告诉你一个秘密,评委最喜欢的时间是猜测最流行的问题.比赛结束后,他们会统计每种颜色的气球并找出结果. 今年,他们决定离开这个可爱的工作给你. ...

  3. dmesg功能介绍

    dmesg 命令的使用范例 ‘dmesg’命令设备故障的诊断是非常重要的.在‘dmesg’命令的帮助下进行硬件的连接或断开连接操作时,我们可以看到硬件的检测或者断开连接的信息.‘dmesg’命令在多数 ...

  4. java 整型数据转换为小数类型 BigDecimal 装换为Double

    A,B为String类型 ,A-B=C BigDecimal A=(BigDecimal) map.get("A"); BigDecimal B=(BigDecimal) map. ...

  5. PHP 使用GD库合成带二维码的海报步骤以及源码实现

    PHP 使用GD库合成带二维码的海报步骤以及源码实现 在做微信项目开发过程中,经常会遇到图片合成的问题,比如将用户的二维码合成到宣传海报中,那么,遇到这种情况,利用PHP的GD库也是很容易实现的,实现 ...

  6. 关于PHPExcel 导出下载表格,调试器响应乱码

    PHPExcel导出表格是日常程序开发很常见的一功能,有些小伙伴千辛万苦把代码写好之后,运行一下结果发现浏览器没反应,表格下载不了或者表格乱码!!!像这种情况有三种解决方法: 1.在header 之前 ...

  7. laravel4.2 Redis 使用

    laravel4.2 Redis 使用 配置文件,app/config/database.php 'redis' => array( 'cluster' => false, 'defaul ...

  8. Go正则处理

    Go语言通过regexp标准包为正则表达式提供了官方支持 包中有三个函数判定是否匹配,匹配返回true,否则返回false,这三个函数只是输入源不同 func Match(pattern string ...

  9. [SGU223]Little Kings(状压DP)

    随便DP一下 Code #include <cstdio> int sta[150],cnt[150],tp,n,k; long long dp[12][144][150],Ans; in ...

  10. 1 多任务fork Unix/Linux/Mac

    # 注意,fork函数,只在Unix/Linux/Mac上运行,windows不可以 1.如下程序,来模拟“唱歌跳舞”这件事情 #-*- coding:utf-8 -*- import time de ...