2-SAT 输出可行解
找可行解的方案就是:
根据第一次建的图建一个反图..然后求逆拓扑排序,建反图的原因是保持冲突的两个事件肯定会被染成不同的颜色
求逆拓扑排序的原因也是为了对图染的色不会发生冲突,输出可行解就是遍历一次逆拓扑排序时染成的颜色,输出同一组颜色的解就是其中的一组可行解。
 
代码:
 #include <stdio.h>
#include <iostream>
#include <string.h>
#include <stack>
#include <queue> const int maxn = ;
const int maxm = ;
struct node{
int u;
int v;
int next;
}edge1[maxm], edge2[maxm];
struct tt{
int s;
int e;
int l;
}tim[maxn];
int n, m, cnt1, cnt2, scc_cnt, dfs_clock;
int head1[maxn], head2[maxn], in[maxn], ct[maxn], ans[maxn];
int sccno[maxn], dfn[maxn], low[maxn], color[maxn];
std::stack<int>st; void init(){
cnt1 = ;
cnt2 = ;
scc_cnt = ;
dfs_clock = ;
memset(in, , sizeof(in));
memset(ans, , sizeof(ans));
memset(color, , sizeof(color));
memset(sccno, , sizeof(sccno));
memset(dfn, , sizeof(dfn));
memset(low, , sizeof(low));
memset(head1, -, sizeof(head1));
memset(head2, -, sizeof(head2));
} void add(int u, int v, struct node edge[], int head[], int &cnt){
edge[cnt].u = u;
edge[cnt].v = v;
edge[cnt].next = head[u];
head[u] = cnt++;
} void dfs(int u){
low[u] = dfn[u] = ++dfs_clock;
st.push(u);
for(int i = head1[u]; i != -; i = edge1[i].next){
int v = edge1[i].v;
if(!dfn[v]){
dfs(v);
low[u] = std::min(low[u], low[v]);
}
else if(!sccno[v]){
low[u] = std::min(low[u], dfn[v]);
}
}
if(low[u]==dfn[u]){
++scc_cnt;
while(){
int x = st.top();
st.pop();
sccno[x] = scc_cnt;
if(x==u) break;
}
}
} void toposort(){
std::queue<int>qu;
for(int i = ; i <= scc_cnt; i++){
if(in[i]==) qu.push(i);
}
while(!qu.empty()){
int u = qu.front();
qu.pop();
if(color[u]==){
color[u] = ;
color[ct[u]] = -;
}
for(int i = head2[u]; i != -; i = edge2[i].next){
int v = edge2[i].v;
--in[v];
if(in[v]==) qu.push(v);
}
}
} int main(){
while(~scanf("%d", &n)){
init();
for(int i = ; i < n; i++){
int s1, s2, t1, t2, l;
int sb = scanf("%d:%d %d:%d %d", &s1, &s2, &t1, &t2, &l);
sb++;
tim[i].s = s1*+s2;
tim[i].e = t1*+t2;
tim[i].l = l;
}
for(int i = ; i < n; i++){
for(int j = ; j < n; j++){
if(i!=j){
if(tim[i].s<tim[j].s+tim[j].l && tim[j].s<tim[i].s+tim[i].l) add(i<<, j<<|, edge1, head1, cnt1);
if(tim[i].s<tim[j].e && tim[j].e-tim[j].l<tim[i].s+tim[i].l) add(i<<, j<<, edge1, head1, cnt1);
if(tim[i].e-tim[i].l<tim[j].s+tim[j].l && tim[j].s<tim[i].e) add(i<<|, j<<|, edge1, head1, cnt1);
if(tim[i].e-tim[i].l<tim[j].e && tim[j].e-tim[j].l<tim[i].e) add(i<<|, j<<, edge1, head1, cnt1);
}
}
}
for(int i = ; i < n+n; i++){
if(!dfn[i]) dfs(i);
}
for(int i = ; i < n+n; i++){
for(int j = head1[i]; j != -; j = edge1[j].next){
int v = edge1[j].v;
if(sccno[i] != sccno[v]){
add(sccno[v], sccno[i], edge2, head2, cnt2);
in[sccno[i]]++;
}
}
}
bool flag = false;
for(int i = ; i < n; i++){
if(sccno[i<<]==sccno[i<<|]){
flag = true;
break;
}
ct[sccno[i<<]] = sccno[i<<|];
ct[sccno[i<<|]] = sccno[i<<];
} if(flag) puts("NO");
else{
toposort();
for(int i = ; i < n+n; i++){
if(color[sccno[i]]==) ans[i] = ;
}
puts("YES");
for(int i = ; i < n; i++) {
if(ans[i<<]) printf("%02d:%02d %02d:%02d\n", tim[i].s/, tim[i].s%, (tim[i].s+tim[i].l)/, (tim[i].s+tim[i].l)%);
else printf("%02d:%02d %02d:%02d\n", (tim[i].e-tim[i].l)/, (tim[i].e-tim[i].l)%, tim[i].e/, tim[i].e%);
}
}
}
return ;
}
 
 

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

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

    Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 11049   Accepted: 3767   Special Judge ...

  2. POJ3683 Priest John's Busiest Day 【2-sat】

    题目 John is the only priest in his town. September 1st is the John's busiest day in a year because th ...

  3. poj3683 Priest John's Busiest Day

    2-SAT. 读入用了黄学长的快速读入,在此膜拜感谢. 把每对时间当作俩个点.如果有交叉代表相互矛盾. 然后tarjan缩点,这样就能得出当前的2-SAT问题是否有解. 如果有解,跑拓扑排序就能找出一 ...

  4. 【POJ3683】Priest John's Busiest Day

    题目 John is the only priest in his town. September 1st is the John's busiest day in a year because th ...

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

  6. 图论(2-sat):Priest John's Busiest Day

    Priest John's Busiest Day   Description John is the only priest in his town. September 1st is the Jo ...

  7. poj 3686 Priest John's Busiest Day

    http://poj.org/problem?id=3683 2-sat 问题判定,输出一组可行解 http://www.cnblogs.com/TheRoadToTheGold/p/8436948. ...

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

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

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

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

随机推荐

  1. [noi2011]道路修建 树形dp

    这道题可以说是树形dp的入门题,也可以看成是一道检验[树]这个数据结构的题目: 这道题只能bfs,毕竟10^6的复杂度win下肯定爆栈了: 但是最恶心的还不是这个,实测用printf输出 用cout输 ...

  2. java socket 一个服务器对应多个客户端,可以互相发送消息

    直接上代码,这是网上找的demo,然后自己根据需求做了一定的修改.代码可以直接运行 服务器端: package socket; import java.io.BufferedReader; impor ...

  3. highchart 导出图片, 显示空白

    使用highchart时, 导出的图片会变空白..   解决方案: 不要加载grid.js

  4. 在 Java EE 组件中使用 Camel Routes

    摘要:你可以通过集成 Camel 和 WildFly 应用服务器(使用 WildFly-Camel 子系统)在 Java EE 组件中开始使用 Apache Camel Routes. [编者按]作者 ...

  5. 关于解压覆盖IIS文件后,新的文件不具备权限导致DMS系统无法正常运行

     向DMS的服务器端站点bin目录覆盖任何补丁文件,请注意:Web站点的bin目录中的文件,IIS的服务进程(Windows2003以上,都是对应Network Services账户)必须对这些文件具 ...

  6. HDU 4169 树形DP

    Wealthy Family Problem Description While studying the history of royal families, you want to know ho ...

  7. WinDbg调试流程的学习及对TP反调试的探索

    基础知识推荐阅读<软件调试>的第十八章 内核调试引擎 我在里直接总结一下内核调试引擎的几个关键标志位,也是TP进行反调试检测的关键位. KdPitchDebugger : Boolean ...

  8. webmatrix

    http://www.microsoft.com/web/webmatrix/ WebMatrix is a free, lightweight, cloud-connected web develo ...

  9. 研究CPU的好文章以及博客

    留个爪,有空仔细看: http://blog.csdn.net/zhangxinrun/article/details/6918862 http://blog.csdn.net/gaijf/artic ...

  10. Android笔记——导入Github开源项目CircleRefreshLayout

    百度n久都找不到android studio导入第三方类库的正确方法,纠结睡不着 ,最后终于蒙到了方法,原来想太多了  ---------------------------------------- ...