POJ3683 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 because there is an old legend in the town that the couple who get married on that day will be forever blessed by the God of Love. This year N couples plan to get married on the blessed day. The i-th couple plan to hold their wedding from time Si to time Ti. According to the traditions in the town, there must be a special ceremony on which the couple stand before the priest and accept blessings. The i-th couple need Di minutes to finish this ceremony. Moreover, this ceremony must be either at the beginning or the ending of the wedding (i.e. it must be either from Si to Si + Di, or from Ti - Di to Ti). Could you tell John how to arrange his schedule so that he can present at every special ceremonies of the weddings.
Note that John can not be present at two weddings simultaneously.
Input
The first line contains a integer N ( 1 ≤ N ≤ 1000). The next N lines contain the Si, Ti and Di. Si and Ti are in the format of hh:mm.
Output
The first line of output contains "YES" or "NO" indicating whether John can be present at every special ceremony. If it is "YES", output another N lines describing the staring time and finishing time of all the ceremonies.
Sample Input
2
08:00 09:00 30
08:15 09:00 20
Sample Output
YES
08:00 08:30
08:40 09:00
Source
POJ Founder Monthly Contest – 2008.08.31, Dagger and Facer
题意:有一个小镇上只有一个牧师。这个小镇上有一个传说,在九月一日结婚的人会受到爱神的保佑,但是要牧师举办一个仪式。这个仪式要么在婚礼刚刚开始的时候举行,要么举行完婚礼正好结束。 现在已知有n场婚礼,告诉你每一场的开始和结束时间,以及举行仪式所需要的时间。问牧师能否参加所有的婚礼,如果能则输出一种方案。
对于每一场婚礼,我们可以把它抽象成一个点对
对于冲突的点,我们可以看做是利用选A不能选B的关系来进行限制
这样这道题就变成了一道2-SAT问题
然后按照套路用tarjan缩点,暴力建反向图,拓扑排序
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<vector>
#include<queue>
#define Pair pair<int,int>
#define F first
#define S second
using namespace std;
const int MAXN=1e6+10;
//#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
char buf[1<<20],*p1=buf,*p2=buf;
inline int read()
{ char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
Pair P[MAXN];
bool check(int x,int y)
{
if((P[x].S<=P[y].F)||(P[x].F>=P[y].S)) return 0;
else return 1;
}
struct node
{
int u,v,nxt;
}edge[MAXN];
int head[MAXN],num=1;
inline void AddEdge(int x,int y)
{
edge[num].u=x;
edge[num].v=y;
edge[num].nxt=head[x];
head[x]=num++;
}
int dfn[MAXN],low[MAXN],vis[MAXN],color[MAXN],colornum=0,tot;
stack<int>s;
void tarjan(int now)
{
dfn[now]=low[now]=++tot;
vis[now]=1;
s.push(now);
for(int i=head[now];i!=-1;i=edge[i].nxt)
{
if(!dfn[edge[i].v])
tarjan(edge[i].v),low[now]=min(low[now],low[edge[i].v]);
else if(vis[edge[i].v])
low[now]=min(low[now],dfn[edge[i].v]);
}
if(dfn[now]==low[now])
{
int h;colornum++;
do
{
h=s.top();s.pop();
color[h]=colornum;
vis[h]=0;
}while(h!=now);
}
}
vector<int>E[MAXN];
int enemy[MAXN],inder[MAXN],ans[MAXN];
void Topsort()
{
queue<int>q;
for(int i=1;i<=colornum;i++)
if(inder[i]==0)
q.push(i);
while(q.size()!=0)
{
int p=q.front();q.pop();
if(!ans[p]) ans[p]=1,ans[enemy[p]]=-1;
for(int i=0;i<E[p].size();i++)
{
inder[E[p][i]]--;
if(inder[E[p][i]]==0) q.push(E[p][i]);
}
}
}
int main()
{
#ifdef WIN32
freopen("a.in","r",stdin);
#else
#endif
memset(head,-1,sizeof(head));
int N=read();
for(int i=1;i<=N;i++)
{
int a,b,c,d,len;
scanf("%d:%d %d:%d %d",&a,&b,&c,&d,&len);
P[i].F=a*60+b;
P[i].S=a*60+b+len;
P[i+N].F=c*60+d-len;
P[i+N].S=c*60+d;
}
for(int i=1;i<=N;i++)
{
for(int j=1;j<=N;j++)
{
if(i==j) continue;
if(check(i,j)) AddEdge(i,j+N);
if(check(i,j+N)) AddEdge(i,j);
if(check(i+N,j)) AddEdge(i+N,j+N);
if(check(i+N,j+N)) AddEdge(i+N,j);
}
}
for(int i=1;i<=N;i++)
if(!dfn[i])
tarjan(i);
for(int i=1;i<=N;i++)
if(color[i]==color[i+N])
{printf("NOn");return 0;}
printf("YESn");
for(int i=1;i<=N;i++)
enemy[color[i]]=color[i+N],
enemy[color[i+N]]=color[i];
for(int i=1;i<=N<<1;i++)
{
for(int j=head[i];j!=-1;j=edge[j].nxt)
{
if(color[i]!=color[edge[j].v])
{
E[color[edge[j].v]].push_back(color[i]);
inder[color[i]]++;
}
}
}
Topsort();
for(int i=1;i<=N;i++)
{
if(ans[color[i]]==1)
printf("%.2d:%.2d %.2d:%.2dn",P[i].F/60,P[i].F%60,P[i].S/60,P[i].S%60);
else
printf("%.2d:%.2d %.2d:%.2dn",P[i+N].F/60,P[i+N].F%60,P[i+N].S/60,P[i+N].S%60);
}
return 0;
}
- 黑暗的内存管理
- 二分查找
- 译文 | Android 开发中利用异步来优化运行速度和性能
- 算法基础6:二叉树查找
- 通过UDP广播实现Android局域网Peer Discovering
- tensorflow读取数据-tfrecord格式
- 用Python使用C语言程序(Windows平台)
- 译文 | 在使用过采样或欠采样处理类别不均衡数据后,如何正确做交叉验证?
- 花式解释AutoEncoder与VAE
- 用CNN做句子分类:CNN Sentence Classification (with Theano code)
- MySQL与Python的交互
- 实时Android语音对讲系统架构
- ElasticSearch优化系列二:机器设置(内存)
- Tensorflow之 CNN卷积神经网络的MNIST手写数字识别
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- PHP _construct()函数讲解
- PHP PDOStatement::rowCount讲解
- Python 如何对文件目录操作
- Python字符串split及rsplit方法原理详解
- Laravel框架文件上传功能实现方法示例
- python中如何写类
- 什么是PHP7中的孤儿进程与僵尸进程
- Python爬虫小例子——爬取51job发布的工作职位
- 详解PHP素材图片上传、下载功能
- Python enumerate() 函数如何实现索引功能
- python打开文件的方式有哪些
- PHP实现二维数组按照指定的字段进行排序算法示例
- python怎么自定义捕获错误
- Codeforces Round #677 (Div. 3)
- PHP PDOStatement::fetchObject讲解