HDU 3062 简单的2-SAT问题
在2-SAT,最让我纠结的还是添加有向线段的函数了
void add_clause(int i,int a,int j,int b)
{
int m=2*i+a;
int n=2*j+b;
G[m^1].push_back(n);
G[n^1].push_back(m);
}
这里a,b因为只有真假两种情况,所以只取0或1,这里表示m V n是正确的,那么意思是取到m^1时,那么n必然得取到
同理取到n^1时,m必然取到,所以两条有向线段就添加成功了
例如这道题给所有夫妻排好序后,1号夫妻的丈夫,和3号夫妻的妻子有矛盾,那么来1号的妻子或3号中的丈夫是肯定成立的
那添加量就可以写成add_clause(1,0,3,1) (0表示妻子,1表示丈夫)
最后添加进去的就是G[3].push_back(7),G[6].push_back(2);
表示1号的丈夫来了,那只能让3号的丈夫来以及
要是3号的妻子来,那么只能让1号的妻子来才不会有矛盾
bool solve()
{
for(int i=0;i<2*n;i+=2){
if(!mark[i]&&!mark[i^1]){
c=0;
if(!dfs(i)){
while(c>0) mark[S[--c]]=0;
if(!dfs(i^1)) return false;
}
}
}
return true;
}
solve()中查找遍所有的夫妻对,表示当且仅当夫妻二人都不能来的时候返回false,否则返回true
总代码如下:
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
#define N 1005*2
bool mark[N];
vector<int> G[N];
int n,c,S[N];
bool dfs(int i)
{
if(mark[i^]) return false;
if(mark[i]) return true;
mark[i]=true;
S[c++]=i;
for(int j=;j<G[i].size();j++)
if(!dfs(G[i][j])) return false;
return true;
}
void init()
{
for(int i=;i<N;i++) G[i].clear();
memset(mark,false,sizeof(mark));
memset(S,,sizeof(S));
}
void add_clause(int i,int a,int j,int b)
{
int m=*i+a;
int n=*j+b;
G[m^].push_back(n);
G[n^].push_back(m);
}
bool solve()
{
for(int i=;i<*n;i+=){
if(!mark[i]&&!mark[i^]){
c=;
if(!dfs(i)){
while(c>) mark[S[--c]]=;
if(!dfs(i^)) return false;
}
} }
return true;
}
int main()
{
int m,a1,a2,c1,c2;
while(scanf("%d%d",&n,&m)!=EOF){
init();
for(int i=;i<m;i++){
scanf("%d%d%d%d",&a1,&a2,&c1,&c2);
add_clause(a1,c1^,a2,c2^);
}
if(solve()) printf("YES\n");
else printf("NO\n");
}
return ;
}
HDU 3062 简单的2-SAT问题的更多相关文章
- HDU 3062 && HDU 1824 && POJ 3678 && BZOJ 1997 2-SAT
一条边<u,v>表示u选那么v一定被选. #include <iostream> #include <cstring> #include <cstdio> ...
- HDU 1564 简单博弈 水
n*n棋盘,初始左上角有一个石头,每次放只能在相邻的四个位置之一,不能操作者输. 如果以初始石头编号为1作为后手,那么对于每次先手胜的情况其最后一步的四周的编号必定是奇数,且此时编号为偶数,而对于一个 ...
- hdu 3062 Party 2-SAT
题目链接:HDU - 3062 有n对夫妻被邀请参加一个聚会,因为场地的问题,每对夫妻中只有1人可以列席.在2n 个人中,某些人之间有着很大的矛盾(当然夫妻之间是没有矛盾的),有矛盾的2个人是不会同时 ...
- hdu 2037简单贪心--活动安排问题
活动安排问题就是要在所给的活动集合中选出最大的相容活动子集合,是可以用贪心算法有效求解的很好例子.该问题要求高效地安排一系列争用某一公共资源的活动.贪心算法提供了一个简单.漂亮的方法使得尽可能多的活动 ...
- HDU 2089 简单数位dp
1.HDU 2089 不要62 简单数位dp 2.总结:看了题解才敲出来的,还是好弱.. #include<iostream> #include<cstring> #i ...
- HDU 1087 简单dp,求递增子序列使和最大
Super Jumping! Jumping! Jumping! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 ...
- hdu 1237 简单计算器
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1237 简单计算器 Description 读入一个只包含 +, -, *, / 的非负整数计算表达式, ...
- HDU 3853LOOPS(简单概率DP)
HDU 3853 LOOPS 题目大意是说人现在在1,1,需要走到N,N,每次有p1的可能在元位置不变,p2的可能走到右边一格,有p3的可能走到下面一格,问从起点走到终点的期望值 这是弱菜做的第 ...
- hdu 3062 2-sat入门题
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3062 #include <cstdio> #include <cmath> # ...
随机推荐
- Vijos p1518河流 树形DP
https://vijos.org/p/1518 这题代码我基本是抄的,实在太难想了.但是也学到了一些东西. 比如:多叉树转二叉树存,这个细细一想,确实使得在dfs的时候,实现起来方便很多. 说一说具 ...
- PHP多图片上传类推荐
多文件上传是PHP中的一个基础应用,反正PHPer都会遇到的问题,现在就介绍一个功能完善.强大的多文件上传类给大家吧,能用上这个类的地方会很多. <?php class Upload{ var ...
- eggs
Description: Erin买了不少鸡蛋,她发现一天吃不完这么多,于是决定把n个同样的鸡蛋放在m个同样的篮子里,允许有的篮子空着不放,请问共有多少种不同的放法呢? 注意:2,1,1和1,2,1 ...
- Understanding Scroll Views 深入理解 scroll view 读书笔记
Understanding Scroll Views 深入理解 scroll view 读书笔记 It may be hard to believe, but a UIScrollView is ...
- 职业生涯手记——电视剧剧情O.O
很多电视剧.偶像剧.电影里出现过一些场景,从来没想过狗血剧情是来源于现实.. 直到上周一开始,我慢慢相信了.. 事情是这样的. 我们小组有个组员H,从上周一开始他每天都去公司的座机电话接1~2个电话, ...
- Hibernate Lazy属性与懒加载 整理
lazy概念:要用到的时候,再去加载,对于关联的集合来说,只有当访问到的时候,才去加载它所关联的集合,比如一个user对应很多权限,只有当user.getRights()的时候,才发出select r ...
- Idea maven项目不能新建package和class的解决方法
如下图,用IDEA新建的maven项目不能新建package,class等 原因是:这里的java文件夹是普通文件夹,要设置为Sources Root.(如下图) 就可以了(见下图)
- TensorFlow低阶API(二)—— 张量
简介 正如名字所示,TensorFlow这一框架定义和运行涉及张量的计算.张量是对矢量和矩阵向潜在的更高维度的泛化.TensorFlow在内部将张量表示为基本数据类型的n维数组. 在编写TensorF ...
- Asp.Net Core 入门(二)——Startup.cs做了什么
上篇介绍了Program.cs中Main做了什么,这篇我们来讨论下Startup.cs它又做了什么呢? 我们新建一个Asp.Net Core Mvc项目,先来开一下Startup的代码 public ...
- python爬虫---实现项目(二) 分析Ajax请求抓取数据
这次我们来继续深入爬虫数据,有些网页通过请求的html代码不能直接拿到数据,我们所需的数据是通过ajax渲染到页面上去的,这次我们来看看如何分析ajax 我们这次所使用的网络库还是上一节的Reques ...