poj 3683(2-SAT+SCC)
https://www.cnblogs.com/violet-acmer/p/9769406.html
参考资料:
[1]:挑战程序设计竞赛
题意:
有n场婚礼,每场婚礼有起始时间si,结束时间ti,还有一个主持仪式需要花费ti时间,ti必须安排在婚礼的开始或者结束。
主持由神父来做,但是只有一个神父,所以各个婚礼的主持时间不能重复,不过神父可以在出席完一个主持仪式后,立刻出席另一个开始时间与其结束时间相等的主持仪式,问你有没有可能正常的安排主持时间,不能输出no,能的话要输出具体的答案:即每个婚礼的主持时间在那个时间段。
题解:
对于每个结婚仪式 i ,只有在开始或结束时进行主持仪式,两种选择,因此可定义变量 Xi;
Xi 为真 <=> 在开始时进行主持仪式
这样,对于婚礼 i 和 j ,如果Si~Si+Di 和 Sj~Sj+Dj 冲突,就有子句 (非Xi V 非Xj) 为真,对于开始和开始,开始和结束,结束和开始,结束和结束分别对应四条子句,也可得到类似的条件。
于是,要保证所有主持仪式的时间不冲突,只要考虑将这些所有的子句用 ^(合取)连接起来所得道德布尔公式就好了。
例如,对于输入的样例可以得到的布尔公式为:

而当x1为真而x2为假时,其值为真。
这样,我们就把原问题转为了2-SAT问题,接下来只要进行强连通分量分解并判断是否有使得布尔公式值为真的一组布尔变量就好了。
以上分析来自挑战程序设计竞赛P326。
难点:
根据2-SAT建立有向图,用SCC分解强连通分量
AC代码:
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cmath>
using namespace std;
#define mem(a,b) (memset(a,b,sizeof a))
#define pb push_back
const int maxn=1e3+; //X1~Xn : 1~n
//非X1~非Xn : n+1~2*n
int n;
int s[maxn];
int t[maxn];
int d[maxn];
vector<int >G[*maxn],rG[*maxn];//注意此处是 2*maxn
vector<int >vs;
int scc[*maxn];
bool vis[*maxn];
void addEdge(int u,int v)
{
G[u].pb(v);
rG[v].pb(u);
}
void SAT()
{
for(int i=;i <= n;++i)
{
for(int j=;j < i;++j)
{
if(max(s[i],s[j]) < min(s[j]+d[j],s[i]+d[i]))//第 i 场婚礼的开始时主持时间与第 j 场婚礼的开始时主持时间冲突
addEdge(i,j+n),addEdge(j,i+n);
if(max(s[i],t[j]-d[j]) < min(t[j],s[i]+d[i]))//第 i 场婚礼的开始时主持时间与第 j 场婚礼的结束时主持时间冲突
addEdge(i,j),addEdge(j+n,i+n);//注意,第二处是 j+n -> i+n
if(max(s[j],t[i]-d[i]) < min(t[i],s[j]+d[j]))//第 i 场婚礼的结束时主持时间与第 j 场婚礼的开始时主持时间冲突
addEdge(i,j),addEdge(i+n,j+n);//注意,第二处是 i+n -> j+n
if(max(t[i]-d[i],t[j]-d[j]) < min(t[i],t[j]))//第 i 场婚礼的结束时主持时间与第 j 场婚礼的结束时主持时间冲突
addEdge(i+n,j),addEdge(j+n,i);
}
}
}
void Dfs(int u)
{
vis[u]=true;
for(int i=;i < G[u].size();++i)
if(!vis[G[u][i]])
Dfs(G[u][i]);
vs.pb(u);
}
void rDfs(int u,int k)
{
vis[u]=true;
scc[u]=k;
for(int i=;i < rG[u].size();++i)
{
int to=rG[u][i];
if(!vis[to])
rDfs(to,k);
}
}
void SCC()
{
mem(vis,false);
vs.clear();
for(int i=;i <= n;++i)
if(!vis[i])
Dfs(i);
mem(vis,false);
int k=;
for(int i=vs.size()-;i >= ;--i)
if(!vis[vs[i]])
rDfs(vs[i],++k);
}
void Init()
{
for(int i=;i < maxn;++i)
G[i].clear(),rG[i].clear();
}
int main()
{ while(~scanf("%d",&n))
{
Init();
for(int i=;i <= n;++i)
{
int h,m;
char ch;
scanf("%d%c%d",&h,&ch,&m);
s[i]=h*+m;//将开始时间转化为分钟
scanf("%d%c%d",&h,&ch,&m);
t[i]=h*+m;//将结束时间转化为分钟
scanf("%d",d+i);
}
SAT();//根据2-SAT建图
SCC();//强连通分量分解
bool flag=false;
for(int i=;i <= n;++i)
if(scc[i] == scc[i+n])
flag=true;
if(flag)
printf("NO\n");
else
{
printf("YES\n");
for(int i=;i <= n;++i)
{
if(scc[i] > scc[i+n])
printf("%02d:%02d %02d:%02d\n",s[i]/,s[i]%,(s[i]+d[i])/,(s[i]+d[i])%);
else
printf("%02d:%02d %02d:%02d\n",(t[i]-d[i])/,(t[i]-d[i])%,t[i]/,t[i]%);
}
}
}
return ;
}
poj 3683(2-SAT+SCC)的更多相关文章
- POJ 3683 Priest John's Busiest Day(2-SAT+方案输出)
Priest John's Busiest Day Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10010 Accep ...
- 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 ...
- POJ 3683 Priest John's Busiest Day (2-SAT+输出可行解)
题目地址:POJ 3683 第一次做须要输出可行解的题目. . .大体思路是先用强连通来推断是否有可行解,然后用逆序建图.用拓扑排序来进行染色.然后输出可行解. 详细思路见传送门 由于推断的时候少写了 ...
- 2-SAT的小总结(POJ 3683 POJ 3207)
记住几个最重要的公式: xANDy=0<=>(x=>y′)AND(y=>x′) xANDy=1<=>(x′=>x)AND(y′=>y) xORy=0&l ...
- poj - 3683 - Priest John's Busiest Day(2-SAT)
题意:有N场婚礼,每场婚礼的开始时间为Si,结束时间为Ti,每场婚礼有个仪式,历时Di,这个仪式要么在Si时刻开始,要么在Ti-Di时刻开始,问能否安排每场婚礼举行仪式的时间,使主持人John能参加所 ...
- poj 3683(2-sat+输出一组可行解)
题目链接:http://poj.org/problem?id=3683 思路:对于每个结婚仪式,只有在开始或结束时进行这两种选择,我们可以定义xi为真当且仅当在开始时进行.于是我们可以通过时间先后确定 ...
- POJ 3683 Priest John's Busiest Day (2-SAT,常规)
题意: 一些人要在同一天进行婚礼,但是牧师只有1个,每一对夫妻都有一个时间范围[s , e]可供牧师选择,且起码要m分钟才主持完毕,但是要么就在 s 就开始,要么就主持到刚好 e 结束.因为人数太多了 ...
- POJ 3683 Priest John's Busiest Day[2-SAT 构造解]
题意: $n$对$couple$举行仪式,有两个时间段可以选择,问是否可以不冲突举行完,并求方案 两个时间段选择对应一真一假,对于有时间段冲突冲突的两人按照$2-SAT$的规则连边(把不冲突的时间段连 ...
- POJ 3683 Priest John's Busiest Day (2-SAT)
Priest John's Busiest Day Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 6900 Accept ...
随机推荐
- 熟记这些git命令,你就是大神
1.git log 查看 提交历史 默认不用任何参数的话,git log 会按提交时间列出所有的更新,最近的更新排在最上面 2.git log -p -2 常用 -p 选项展开显示每次提交的内容差异 ...
- 几何学观止(Riemann流形部分)
上承这个页面,相较之前,增加了古典的曲线曲面论,这部分介绍得很扼要,Riemann流形介绍得也很快,花了仅仅30页就介绍到了Gauss-Bonnet公式.同时配上了提示完整的习题. 几何学观止-Rie ...
- 快速搭建BIND服务,并实现解析
公司有测试需求,当连接一个网络后自动会进入产品的测试环境,所以搭建了一个DNS解析服务,来完成此需求. 参考:http://blog.chinaunix.net/uid-30149335-id-506 ...
- uml 图学习记录
UML类图与类的关系详解 2011-04-21 来源:网络 在画类图的时候,理清类和类之间的关系是重点.类的关系有泛化(Generalization).实现(Realization).依赖(D ...
- 实现基于SSH的门票管理系统开发的质量属性
我要做的是一个基于SSH的门票售卖系统,在系统中常见的质量属性有:可用性.可修改性.性能.安全性.易用性. 可用性方面: 可用性是指系统正常运行时间的比例,是通过两次故障之间的时间长度或在系统崩溃情况 ...
- 第一次Spring总结
第一阶段:下载了类似app使用,并做了对比,分析,对自己的app有了一些构思,完成了环境的配置.在这一阶段,一开始只有两个女生显得有点弱,面对从未接触过的app项目,首先就是配置环境方面的,在经过班上 ...
- [BUAA_SE_2017]个人项目-Sudoku
个人项目作业-数独 Github项目地址 时间预估 PSP2.1 Personal Software Process Stages 预估时间(分钟) 实际耗时(分钟) Planning 计划 60 · ...
- [转帖]IIS内虚拟站点配置信息说明
web.config配置详细说明 https://www.cnblogs.com/zhangxiaolei521/p/5600607.html 原作者总结的很详细 但是没有完全的看完 自己对IIS 的 ...
- Oracle一次可以查询多个表的结果的方法
select (select count(1) from gspauresult) 权限总表, (select count(1) from gspau01result) 权限总表1, (select ...
- cmd 安装mysql
838444958 http://www.runoob.com/mysql/mysql-install.html (cmd)Aa410766383 mysql password bin目录下 ...