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. 通过ES6写法去对Redux部分源码解读

    在Redux源码中主要有四个文件createStore,applyMiddleware,bindActionCreators,combineRedures createStore.js export ...

  2. PHP的抽象类和抽象方法以及接口总结

    PHP中的抽象类和抽象方法自己用的不多,但是经常会在项目中看到别人使用,同样,今天在看别人的代码的时候,发现使用了抽象类,就总结下: 抽象类:1.如果一个类中有一个方法是抽象方法,则这个类就是抽象类: ...

  3. 【读书笔记 - Effective Java】04. 通过私有构造器强化不可实例化的能力

    工具类(utility class)不希望被实例化,比如只包含静态方法和静态域的类.为了这个目的,需要让这个类包含一个私有构造器. // 私有构造器示例 public class UtilityCla ...

  4. Git 学习笔记–基本操作

    Git 与 SVN 不同,是分布式的版本控制系统,不需要主服务器即可工作,实际中为了方便各个工作者间同步工作,通常还是会设置主服务器. Git的设置及初始化: 设置全局用户信息: luojiahu@u ...

  5. Spring异常重试框架Spring Retry

    Spring Retry支持集成到Spring或者Spring Boot项目中,而它支持AOP的切面注入写法,所以在引入时必须引入aspectjweaver.jar包. 快速集成的代码样例: @Con ...

  6. PHP7.1中使用openssl替换mcrypt

    PHP7.1中使用openssl替换mcrypt 在php开发中,使用mcrypt相关函数可以很方便地进行AES加.解密操作,但是PHP7.1中废弃了mcrypt扩展,所以必需寻找另一种实现.在迁移手 ...

  7. WIN10远程连接winserver2012 r2,连接失败

    背景:2012开启远程的时候,默认是勾选“仅允许运行使用网络级别身份验证的远程桌面的计算机连接”,这个选项据说比较安全,但是用win10远程的时候就报错,函数不受支持,最后通过修改win10的配置得以 ...

  8. STM32 硬件UART接收超时检测设置

    STM32 硬件UART接收超时检测设置 -----------------本文作者"智御电子",期待与电子爱好者交流学习.---------------- 应用场景 在uart应 ...

  9. 动态的GRE OVER IPSEC的实验模拟与分析

    此篇博客正在介绍的是下图中的Dynamic P2P GRE OVER IPSEC VPN: 为什么出现这种动态的GRE OVER IPSEC VPN技术呢? 首先在前面几篇博客中已经介绍过了,动态是为 ...

  10. [WebService] 使用httpWebrequest 调用并调试WebService

    使用httpWebrequest 调用并调试WebService. 首先  使用httpWebrequest 调用WebService 代码: using System.Net;            ...