题意:有N场婚礼,每场婚礼的开始时间为Si,结束时间为Ti,每场婚礼有个仪式,历时Di,这个仪式要么在Si时刻开始,要么在Ti-Di时刻开始,问能否安排每场婚礼举行仪式的时间,使主持人John能参加所有的这些仪式的全过程。

题目链接:http://poj.org/problem?id=3683

——>>每场婚礼的仪式,要么在开始段举行,要么在结束段举行,且一定要举行,要求各场婚礼仪式没冲突——>>2-SAT。。。

2-SAT挺神,针对此类问题,可谓手到擒来。。。

LJ《训练指南》上的写法挺容易理解的。。。于是用上了。。。(相对于2003年伍昱论文中O(n)的算法,在时间上《训练指南》中的写法比不上)。。。

对于2-SAT,建图非常重要。。。

——>>设一场婚礼为i,mark[2*i] == 1表示在其开始段举行仪式,mark[2*i+1] == 1表示在其结束段举行仪式。。。

建图思路:对于一个仪式i和另一个仪式j,若i与j有冲突,则说明i不能举行或者j不能举行。。。即i == 0 || j == 0,所以,i' -> j,j' -> i。。。

#include <cstdio>
#include <cstring>
#include <vector> using namespace std; const int maxn = 1000 + 10; int N;
int S[maxn], S1[maxn], S2[maxn], T[maxn], T1[maxn], T2[maxn], D[maxn];
int t[maxn][2]; struct Twoset {
int n;
vector<int> G[maxn*2];
bool mark[maxn*2];
int stk[maxn*2], c; void init(int n) {
this->n = n;
for(int i = 0; i < 2*n; i++) G[i].clear();
memset(mark, 0, sizeof(mark));
} void add_clause(int x, int xval, int y, int yval) {
x = x * 2 + xval;
y = y * 2 + yval;
G[x^1].push_back(y);
G[y^1].push_back(x);
} bool dfs(int x) {
if(mark[x^1]) return false;
if(mark[x]) return true;
mark[x] = true;
stk[++c] = x;
int sz = G[x].size();
for(int i = 0; i < sz; i++) {
int v = G[x][i];
if(!dfs(v)) return false;
}
return true;
} bool YES() {
for(int i = 0; i < 2*n; i += 2) if(!mark[i] && !mark[i+1]) {
c = 0;
if(!dfs(i)) {
while(c) mark[stk[c--]] = false;
if(!dfs(i+1)) return false;
}
}
return true;
} void solve() {
if(YES()) {
puts("YES");
for(int i = 0; i < 2*n; i++) if(mark[i]) {
int id = i / 2;
if(i&1) printf("%02d:%02d %02d:%02d\n", (T[id]-D[id])/60, (T[id]-D[id])%60, T[id]/60, T[id]%60);
else printf("%02d:%02d %02d:%02d\n", S[id]/60, S[id]%60, (S[id]+D[id])/60, (S[id]+D[id])%60);
}
}
else puts("NO");
}
} solver; bool isok(int L1, int R1, int L2, int R2) { //判断两个仪式是否冲突
return R1 <= L2 || R2 <= L1;
} void read() {
for(int i = 0; i < N; i++) {
scanf("%d:%d %d:%d %d", &S1[i], &S2[i], &T1[i], &T2[i], &D[i]);
S[i] = S1[i] * 60 + S2[i];
T[i] = T1[i] * 60 + T2[i];
t[i][0] = S[i];
t[i][1] = T[i] - D[i];
}
} void build() {
for(int i = 0; i < N; i++) for(int a = 0; a < 2; a++)
for(int j = i+1; j < N; j++) for(int b = 0; b < 2; b++)
if(!isok(t[i][a], t[i][a]+D[i], t[j][b], t[j][b]+D[j])) //有冲突,不能同时赋a,b,所以a^1或者b^1成立
solver.add_clause(i, a^1, j, b^1);
} int main()
{
while(scanf("%d", &N) == 1) {
solver.init(N);
read();
build();
solver.solve();
}
return 0;
}

poj - 3683 - Priest John's Busiest Day(2-SAT)的更多相关文章

  1. POJ 3683 Priest John's Busiest Day (2-SAT)

    Priest John's Busiest Day Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6900   Accept ...

  2. POJ 3683 Priest John's Busiest Day(2-SAT+方案输出)

    Priest John's Busiest Day Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10010   Accep ...

  3. POJ 3683 Priest John's Busiest Day(2-SAT 并输出解)

    Description John is the only priest in his town. September 1st is the John's busiest day in a year b ...

  4. POJ 3683 Priest John's Busiest Day / OpenJ_Bailian 3788 Priest John's Busiest Day(2-sat问题)

    POJ 3683 Priest John's Busiest Day / OpenJ_Bailian 3788 Priest John's Busiest Day(2-sat问题) Descripti ...

  5. POJ 3683 Priest John's Busiest Day (2-SAT)

    题意:有n对新人要在同一天结婚.结婚时间为Ti到Di,这里有时长为Si的一个仪式需要神父出席.神父可以在Ti-(Ti+Si)这段时间出席也可以在(Di-Si)-Si这段时间.问神父能否出席所有仪式,如 ...

  6. POJ 3683 Priest John's Busiest Day (2-SAT,常规)

    题意: 一些人要在同一天进行婚礼,但是牧师只有1个,每一对夫妻都有一个时间范围[s , e]可供牧师选择,且起码要m分钟才主持完毕,但是要么就在 s 就开始,要么就主持到刚好 e 结束.因为人数太多了 ...

  7. POJ 3683 Priest John's Busiest Day[2-SAT 构造解]

    题意: $n$对$couple$举行仪式,有两个时间段可以选择,问是否可以不冲突举行完,并求方案 两个时间段选择对应一真一假,对于有时间段冲突冲突的两人按照$2-SAT$的规则连边(把不冲突的时间段连 ...

  8. POJ 3683 Priest John's Busiest Day 【2-Sat】

    这是一道裸的2-Sat,只要考虑矛盾条件的判断就好了. 矛盾判断: 对于婚礼现场 x 和 y,x 的第一段可以和 y 的第一段或者第二段矛盾,同理,x 的第二段可以和 y 的第一段或者第二段矛盾,条件 ...

  9. POJ 3683 Priest John's Busiest Day

    看这个题目之前可以先看POJ2186复习一下强联通分量的分解 题意:给出N个开始时间和结束时间和持续时间三元组,持续时间可以在开始后或者结束前,问如何分配可以没有冲突. -----–我是分割线---- ...

随机推荐

  1. jquery中html()/text()/val()区别

    html就是你可以添加<span></span><li></li>的标记text只能写文本如果写了上面的标记则会以文本形式输出,就是输出标签体的内容va ...

  2. 多核模糊C均值聚类

    摘要: 针对于单一核在处理多数据源和异构数据源方面的不足,多核方法应运而生.本文是将多核方法应用于FCM算法,并对算法做以详细介绍,进而采用MATLAB实现. 在这之前,我们已成功将核方法应用于FCM ...

  3. 【转】Core Bluetooth框架之一:Central与Peripheral

    原文网址:http://southpeak.github.io/blog/2014/07/29/core-bluetoothkuang-jia-zhi-%5B%3F%5D-:centralyu-per ...

  4. ios 内存管理 心得

    - alloc, copy, retain会把引用计数+1 - release会把引用计数-1 - 局部变量如果初始化时不是autorelease的,要及时调用release释放,并且赋值为nil否则 ...

  5. hdu 2897(威佐夫博奕变形)

    题意:容易理解. 分析:当n%(p+q)==0时,先取者必胜,必胜方案:先取q,然后对方去x个,先取者就取(p+q-x)个,最后对方就必须取玩p个, 当n%(p+q)==r(r<=p),先取者必 ...

  6. PHP如何返回json格式的数据

    我们常见一些网站在做ajax时返回JSON格式的数据: 返回的是json格式的数据 这有什么好处那?很显然前端在接到返回的数据时可以直接使用,而不用再用eval('(+ returnString +) ...

  7. 基类,派生类,内存分配情况 .xml

    pre{ line-height:1; color:#1e1e1e; background-color:#d2d2d2; font-size:16px;}.sysFunc{color:#627cf6; ...

  8. javascript --- jQuery --- Deferred对象

    javascript --- jQuery --- Deferred对象 javascript的函数式编程是多么引人入胜,jQuery使代码尽可能的精简,intelligent! defer - 必应 ...

  9. bzoj1251 序列终结者(splay)

    人生第一发splay,写得巨丑,最后忘记了push_down以后要将子节点maintain 9k代码不忍直视 #define NDEBUG #include<cstdio> #includ ...

  10. 【LeetCode】27 - Remove Element

    Given an array and a value, remove all instances of that value in place and return the new length. T ...