看这个题目之前可以先看POJ2186复习一下强联通分量的分解

题意:给出N个开始时间和结束时间和持续时间三元组,持续时间可以在开始后或者结束前,问如何分配可以没有冲突。

—————–我是分割线———————————

先解释一下合取范式(离散数学已经学过):

如果合取范式中的每个字句的文字个数不超过两个就称为2-SAT问题

一般性称为n-SAT问题

举个栗子:(a∨b)∧¬a" role="presentation" style="position: relative;">(a∨b)∧¬a(a∨b)∧¬a 在a为false而b为true时整个范式的取值为真。

利用强连通分量的知识,就可以在布尔公式字句个数的线性时间内解决2-SAT问题。在离散数学中我们已经学过蕴含范式。对于a∨b" role="presentation" style="position: relative;">a∨ba∨b可以转换为(¬a⇒b)∧(¬b⇒a)" role="presentation" style="position: relative;">(¬a⇒b)∧(¬b⇒a)(¬a⇒b)∧(¬b⇒a)

下面就是建图过程了:

对于每一个布尔变量x,构造两个顶点x和¬x" role="presentation" style="position: relative;">¬x¬x;以⇒" role="presentation" style="position: relative;">⇒⇒为有向边建立有向图。

在有向图中,如果a能到达b的话,a为真则b也为真。

因此在同一个强连通分量中所含的所有文字代表的布尔值都相同。

特别注意的是,假设x和x̸" role="presentation" style="position: relative;">x̸x̸都在同一个强连通分量中,则显然,这个强连通分量始终不可能为真。

相反,如果不存在这样的布尔变量,对于每个布尔变量x,让

x所在的强连通分量的拓扑序在¬x" role="presentation" style="position: relative;">¬x¬x所在的强连通分量之后,(也就是比较二者的拓扑序)

就是使得该公式的值为真的一组合适的布尔变量的解。

——————-我是分割线————————-

对于每个三元组,只有在开始之后和结束之前两种选择,不妨设变量xi

xi为真<->在开始之后开始插入时间长度

有了这些理论支持,对于每个三元组,无非有四种组合情况:

开始-开始

开始和结束

结束-开始

结束-结束

(本题中样例中没有结束-开始)

如果开始-开始冲突,那么¬x1∨¬x2" role="presentation" style="position: relative;">¬x1∨¬x2¬x1∨¬x2的值为真。

所以合取范式为:(¬x1∨¬x2)∧(¬x1∨x2)∧(x1∨x2)" role="presentation" style="position: relative;">(¬x1∨¬x2)∧(¬x1∨x2)∧(x1∨x2)(¬x1∨¬x2)∧(¬x1∨x2)∧(x1∨x2)

当x1的值为真x2的值为假时,其值为真。

接下来就是进行强连通分量分解并判断是否有使得布尔公式的值为真的一组布尔变量赋值。

(这里利用带了前面的那个定理:如果x所在的强连通分量的拓扑序在¬x之后,则x为真" role="presentation" style="position: relative;">¬x之后,则x为真¬x之后,则x为真

#include <iostream>
#include <map>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <set>
#include <cmath>
using namespace std;
#define IOS std::ios::sync_with_stdio (false);std::cin.tie(0)
#define pb push_back
#define PB pop_back
#define bk back()
#define fs first
#define se second
#define sq(x) (x)*(x)
#define eps (3e-7)
#define IINF (1<<29)
#define LINF (1ll<<59)
#define INF (1000000000)
#define FINF (1e3)
#define clr(x) memset((x),0,sizeof (x));
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<int,int> P; const int maxn=2005;
int n;
int a[maxn][3];
char r[300];
vector<int> G[maxn],rG[maxn],od;
bool vis[maxn];
int sccid[maxn];
int get(char a,char b){
return (a-'0')*10+b-'0';
}
bool inter(int a,int b,int c,int d){
return !(a>=d||b<=c);
}
void addedge(int a,int b){
G[a].pb(b);
rG[b].pb(a);
}
void dfs1(int v){
vis[v]=1;
for(int i=0;i<G[v].size();i++){
int u=G[v][i];
if(!vis[u]) dfs1(u);
}
od.pb(v);
}
void dfs2(int v,int k){
vis[v]=1;
sccid[v]=k;
for(int i=0;i<rG[v].size();i++){
int u=rG[v][i];
if(!vis[u]) dfs2(u,k);
}
}
int V;
void scc(){
clr(vis);od.clear();
for(int i=1;i<=V;i++){
if(!vis[i]) dfs1(i);
}
clr(vis);
int id=1;
for(int i=od.size()-1;i>=0;i--){
int v=od[i];
if(!vis[v]) dfs2(v,id++);
}
}
void build(){
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
if(inter(a[i][0],a[i][0]+a[i][2],a[j][0],a[j][0]+a[j][2])){
addedge(i,j+n);
addedge(j,i+n);
}
if(inter(a[i][0],a[i][0]+a[i][2],a[j][1]-a[j][2],a[j][1])){
addedge(i,j);
addedge(j+n,i+n);
}
if(inter(a[i][1]-a[i][2],a[i][1],a[j][0],a[j][0]+a[j][2])){
addedge(i+n,j+n);
addedge(j,i);
}
if(inter(a[i][1]-a[i][2],a[i][1],a[j][1]-a[j][2],a[j][1])){
addedge(i+n,j);
addedge(j+n,i);
}
}
}
}
bool ans[maxn];
int main(){
freopen("/home/slyfc/CppFiles/in","r",stdin);
//freopen("defense.in","r",stdin);
//freopen("defense.out","w",stdout);
cin>>n;
V=n*2;
for(int i=1;i<=n;i++){
scanf("%s",r);
a[i][0]=get(r[0],r[1])*60+get(r[3],r[4]);
scanf("%s",r);
a[i][1]=get(r[0],r[1])*60+get(r[3],r[4]);
scanf("%d",&a[i][2]);
}
build();
scc();
for(int i=1;i<=n;i++){
if(sccid[i]==sccid[i+n]){
puts("NO");
return 0;
}else{
if(sccid[i]>sccid[i+n]){
ans[i]=1;
}else{
ans[i]=0;
}
}
}
puts("YES");
for(int i=1;i<=n;i++){
if(ans[i]){
int s=a[i][0],t=a[i][0]+a[i][2];
printf("%02d:%02d %02d:%02d\n",s/60,s%60,t/60,t%60);
}else{
int s=a[i][1]-a[i][2],t=a[i][1];
printf("%02d:%02d %02d:%02d\n",s/60,s%60,t/60,t%60);
}
}
return 0;
}

POJ 3683 Priest John's Busiest Day的更多相关文章

  1. 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 ...

  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)

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

  4. 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 ...

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

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

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

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

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

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

  8. POJ 3683 Priest John's Busiest Day

    2-SAT简单题,判断一下两个开区间是否相交 #include<cstdio> #include<cstring> #include<cmath> #include ...

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

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

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

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

随机推荐

  1. wikioi 2147 bitset+map解决

    题目描写叙述 Description 小明是一名天文爱好者,他喜欢晚上看星星.这天,他从淘宝上买下来了一个高级望远镜.他十分开心.于是他晚上去操场上看星星. 不同的星星发出不同的光,他的望远镜能够计算 ...

  2. 跟着9张思维导图学JavaScript

    思维导图小tips 思维导图又叫心智图,是表达发射性思维的有效的图形思维工具 ,它简单却又极其有效,是一种革命性的思维工具.思维导图运用图文并重的技巧,把各级主题的关系用相互隶属与相关的层级图表现出来 ...

  3. 学习Centos 7的笔记

    Step-1 yum install epel-release && yum clean all && yum update –y &&  yum -y ...

  4. 【剑指Offer】俯视50题之21 - 30题

    面试题21包括min函数的栈  面试题22栈的压入.弹出序列  面试题23从上往下打印二叉树  面试题24二叉搜索树的后序遍历序列  面试题25二叉树中和为某一值的路径  面试题26复杂链表的复制  ...

  5. 使用Blender批量导出/转换模型

    2.4版本号的Blender API和2.5以上版本号的API有非常大的不同,这里仅仅是提供了思路和2.4版本号的导出方案. 先提供一个脚本,这个是由Blender调用的.用于转换Ogre的Mesh文 ...

  6. Java 中 泛型的限定

         泛型 一般 出如今集合中,迭代器中 也会出现!      泛型 是为了 提高代码的 安全性. 泛型 确保数据类型的唯一性. 在我们经常使用的容器中.  越是 单一 约优点理啊!       ...

  7. 【iOS系列】-autorelease的作用

    内存管理原则(配对原则):只要出现了new,alloc,retain方法,就要配对出现release,autorelease   1:对象存入到自动释放池中,当这个池子被销毁的时候他会对池子中所有的对 ...

  8. mysql字段去重方式

    一直找不出某个字段去重的前提下,还能够显示其它字段的数据 以下是解决方法: SELECT *, COUNT(DISTINCT( province)) FROM area_info WHERE type ...

  9. nhibernate实体类主键ID赋值问题

    有个同事忽然来找我,说他遇到了一个问题,在调用nhibernate 进行update数据的时候报错,说是有数据行锁定. 看代码,没啥问题. 直接在PL/SQL developer里对数据库进行插入,也 ...

  10. CodeChef Consecutive Snakes 三分(整数)

    题意 在年度阅兵中,所有的士兵蛇都在阅兵场集合了,但这些蛇的站位不对.整场阅兵必须能从主席台看清楚,所有蛇都应该站成一排.但这些士兵非常懒惰,你必须指挥士兵重新排队,使得所有人的移动距离之和最短. 形 ...