[2-sat]HDOJ1824 Let's go home

中问题 题意略

HDOJ 3062一样

这里 每个队员都有 选 和 不选 两种, 即 上篇所说的$x$和$x’$

建图:队长(a)留下或者其余两名队员(b、c)同时留下

那么就是$a‘ \Rightarrow b$ 、 $a‘ \Rightarrow c$  (队长不在 b必须在, 队长不在 c必须在)

       以及$b‘ \Rightarrow a$ 、$c‘ \Rightarrow a$  (b不在 队长必须在,c不在 队长必须在)

    每一对队员,如果队员A留下,则队员B必须回家休息下,或者B留下,A回家

    那么就是$A \Rightarrow B’$  (A在 则B必须不在)      以及   $B \Rightarrow A‘$ (B在 则A必须不在)

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 typedef pair<int, int> PI;
 5 #define INF 0x3f3f3f3f
 6
 7 const int N=3005*2;
 8 const int M=N*N;
 9 //注意n是拆点后的大小 即 n <<= 1 N为点数(注意要翻倍) M为边数 i&1=0为i真 i&1=1为i假
10 struct Edge
11 {
12     int to, nex;
13 }edge[M];
14 //注意 N M 要修改
15 int head[N], edgenum;
16 void addedge(int u, int v)
17 {
18     Edge E={v, head[u]};
19     edge[edgenum]=E;
20     head[u]=edgenum++;
21 }
22
23 bool mark[N];
24 int Stack[N], top;
25 void init()
26 {
27     memset(head, -1, sizeof(head));
28     edgenum=0;
29     memset(mark, 0, sizeof(mark));
30 }
31
32 bool dfs(int x)
33 {
34     if(mark[x^1])
35         return false;//一定是拆点的点先判断
36     if(mark[x])
37         return true;
38     mark[x]=true;
39     Stack[top++]=x;
40     for(int i=head[x];i!=-1;i=edge[i].nex)
41         if(!dfs(edge[i].to))
42             return false;
43
44     return true;
45 }
46
47 bool solve(int n)
48 {
49     for(int i=0;i<n;i+=2)
50         if(!mark[i] && !mark[i^1])
51         {
52             top=0;
53             if(!dfs(i))
54             {
55                 while(top)
56                     mark[Stack[--top]]=false;
57                 if(!dfs(i^1))
58                     return false;
59             }
60         }
61     return true;
62 }
63
64 int main()
65 {
66     int n, m;
67     while(~scanf("%d%d", &n, &m))
68     {
69         int nn=n*3;
70         init();
71         while(n--)
72         {
73             int a, b, c;
74             scanf("%d%d%d", &a, &b, &c);
75             addedge(a*2+1, b*2);
76             addedge(a*2+1, c*2);
77             addedge(b*2+1, a*2);
78             addedge(c*2+1, a*2);
79         }
80         while(m--)
81         {
82             int x, y;
83             scanf("%d%d", &x, &y);
84             addedge(x*2, y*2+1);
85             addedge(y*2, x*2+1);
86         }
87         solve(nn)? puts("yes"): puts("no");
88     }
89     return 0;
90 }

HDOJ 1824

[2-sat]HDOJ1824 Let's go home

时间: 2024-11-09 23:21:37

[2-sat]HDOJ1824 Let's go home的相关文章

LA 3211 飞机调度(2—SAT)

https://vjudge.net/problem/UVALive-3211 题意: 有n架飞机需要着陆,每架飞机都可以选择“早着陆”和“晚着陆”两种方式之一,且必须选择一种,第i架飞机的早着陆时间为E,晚着陆时间为L,不得在其他时间着陆.你的任务是为这些飞机安排着陆方式,使得整个着陆计划尽量安全.换句话说,如果把所有飞机的实际着陆时间按照从早到晚的顺序排列,相邻两个着陆时间间隔的最小值. 思路: 二分查找最大值P,每次都用2—SAT判断是否可行. 1 #include<iostream>

8.3吝啬SAT问题

吝啬SAT问题是这样的:给定一组子句(每个子句都是其中文字的析取)和整数k,求一个最多有k个变量为true的满足赋值--如果该赋值存在.证明吝啬SAT是NP-完全问题. 1.易知吝啬SAT的解可以在多项式时间内验证,因此属于NP问题. 2.如果我们把吝啬SAT问题中的k设置为输入的数目,那么SAT问题就可以规约到吝啬SAT问题,所以吝啬SAT问题是np-完全问题.

POJ 3207 Ikki&#39;s Story IV - Panda&#39;s Trick(2 - sat啊)

题目链接:http://poj.org/problem?id=3207 Description liympanda, one of Ikki's friend, likes playing games with Ikki. Today after minesweeping with Ikki and winning so many times, he is tired of such easy games and wants to play another game with Ikki. liy

多边形碰撞 -- SAT方法

检测凸多边形碰撞的一种简单的方法是SAT(Separating Axis Theorem),即分离轴定理. 原理:将多边形投影到一条向量上,看这两个多边形的投影是否重叠.如果不重叠,则认为这两个多边形是分离的,否则找下一条向量来继续投影.我们不需要比较很多条向量,因为已经在数学上证明,多边形每条边的垂直向量就是我们需要的向量. 1.AABB 让我们首先以AABB开始(AABB是一种两边分别平行于X-Y轴的矩形) 判断两个AABB是否碰撞,我们只需要投影两次,分别是投影在平行于X轴和Y轴的向量上

hdu 4751 Divide Groups 2—sat问题 还是未理解

Divide Groups Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1443    Accepted Submission(s): 512 Problem Description This year is the 60th anniversary of NJUST, and to make the celebration mor

HIT 1917 2—SAT

题目大意:一国有n个党派,每个党派在议会中都有2个代表, 现要组建和平委员会,要从每个党派在议会的代表中选出1人,一共n人组成和平委员会. 已知有一些代表之间存在仇恨,也就是说他们不能同时被选为和平委员会的成员, 现要你判断满足要求的和平委员会能否创立?如果能,请任意给出一种方案.( POI 0106 ) ----------------------------------------- 这道题就是裸的2-SAT 不过我用了tarjan缩点 然后一波拓排 tips:一个问题无解当且仅当一个集合的

2—SAT问题

现有一个由N个布尔值组成的序列A,给出一些限制关系,比如A[x] AND A[y]=0.A[x] OR A[y] OR A[z]=1.A[x] XOR A[y]=0等,要确定A[0..N-1]的值,使得其满足所有限制关系.这个称为SAT问题,特别的,若每种限制关系中最多只对两个元素进行限制,则称为2-SAT问题. 对于x.y有11种关系,将其拆点2x(假),2x+1(真).对于x为假或者y为假这样的条件,我们连两条有向边2x+1->2y.2y+1->2x,注意这里是有向边以及边的起点和终点的关

SAT考试里最难的数学题? &middot; 三只猫的温暖

问题 今天无意中在Quora上看到有人贴出来一道号称是SAT里最难的一道数学题,一下子勾起了我的兴趣.于是拿起笔来写写画画,花了差不多十五分钟搞定.觉得有点意思,决定把解题过程记下来.原帖的图太小,我用GeoGebra重新画了一遍.没错,我就是强迫症. 为了省事,就把这道题叫做RASBTC. In the figure above, arc (text{SBT}) is one quarter of a circle with center (text{R}) and radius 6. If

SAT求解器变元活跃度计算模式的切换

变元活跃度计算模式有:VSIDS.基于历史出现时刻与当前冲突时刻距离等 有三个最小堆: // A priority queue of variables ordered with respect to the variable activity. Heap<VarOrderLt> order_heap_CHB,                                order_heap_VSIDS, order_heap_distance; 一般的求解切换方式是: conflicts