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. 在当前iframe中, 获取Iframe的id

    window.frameElement   返回嵌入当前window对象的元素(比如 <iframe> 或者 <object>),如果当前window对象已经是顶层窗口,则返回 ...

  2. 百度Hi之CSRF蠕虫攻击

    漏洞起因:百度是国内最大的中文搜索引擎.同时百度也提供了百度空间.百度贴吧等BLOG社区服务,拥有海量的用户群,号称全球最大中文社区. 80sec发现过百度产品一系列的安全漏洞,其中一些问题得到了有效 ...

  3. DSP中的cmd文件

    一.CMD文件 链接命令文件(Link Command Files),以后缀.cmd结尾,简称CMD文件. CMD文件的两大功能是指示存储空间和分配段到存储空间. 在编写CMD文件时,主要采用MEMO ...

  4. 如何让360、遨游、猎豹等双核浏览器默认以webkit内核渲染网页?

    众知目前国内不少浏览器都自称双核,一般是 IE(Trident)+Webkit.因为 webkit 急速的体验和对 HTML5 的支持,有些情况下开发者可能希望用户优先甚至只使用 webkit 内核渲 ...

  5. 提高Asp.Net应用程序性能的十大方法(译感)

    译完了提高Asp.Net应用程序的十大方法这篇文章,仔细想其中提到的每一条,在这里结合我的项目来谈谈.第一条:返回多个结果集因为我的项目中所有对数据库的访问的sql语句都是通过调用存储过程实现的,所以 ...

  6. display:inline-block 在IE6中实现{转}

    IE6/IE7下对display:inline-block的支持性不好. 1.inline元素的display属性设置为inline-block时,所有的浏览器都支持: 2.block元素的displ ...

  7. POJ 1679 The Unique MST(次小生成树)

    题意:求解最小生成树的权值是否唯一,即要我们求次小生成树的权值两种方法求最小生成树,一种用prim算法, 一种用kruskal算法 一:用prim算法 对于给定的图,我们可以证明,次小生成树可以由最小 ...

  8. 2014多校第六场 1010 || HDU 4930 Fighting the Landlords (模拟)

    题目链接 题意 : 玩斗地主,出一把,只要你这一把对方要不了或者你出这一把之后手里没牌了就算你赢. 思路 : 一开始看了第一段以为要出很多次,实际上只问了第一次你能不能赢或者能不能把牌出尽. #inc ...

  9. arcgis地图操作的资料URL,以供以后查阅

    更改Arcgis Web应用程序的端口号8399: http://help.arcgis.com/zh-cn/arcgisserver/10.0/help/arcgis_server_java_hel ...

  10. 小鲜肉初学JS做得仿京东淘宝竖排二级导航

    <!DOCTYPE html><html><head><meta charset="utf-8"><meta http-equ ...