当前位置: 首页 > 编程日记 > 正文

POJ 3683 【2-sat+求一组可行解】.cpp

题意:

  有一个牧师要给好几对新婚夫妇准备婚礼..

  已知每对新婚夫妇的有空的时间以及婚礼持续时间..

  问是否可以让每对新婚夫妇都得到该牧师的祝福~

  如果可以就输出YES以及可行解 不可以就输出NO

输入:

  一个n 表示有n对新婚夫妇

  接下来n行每行a b c 表示在a~b这段时间有空..以及婚礼会持续 c..

  P.S.时间只可以选在a开始或者b结束..

  eg:08:00 09:00 30 可以在8:00~8:30举行婚礼或者8:30~9:00举行婚礼

思路:

  2-sat 以在前一段时间举行婚礼或者后一段时间举行婚礼为2个可选方案

  然后每对新婚夫妇婚礼时间冲突了就给和另外一个方案连线..

  2-sat问题连边的要求就是这两个情况一定要同时发生..

  然后根据建的图求强连通分量以及缩点..表示是否可以同时发生并方便后面拓扑排序..

  总方案不成立的条件是一个强连通分量里有col[ i ] == col[ i+n ]

 

  而找可行解的方案就是:

  根据第一次建的图建一个反图..然后求逆拓扑排序..

  建反图的原因是保持冲突的两个事件肯定会被染成不同的颜色..

  求逆拓扑排序的原因也是为了对图染的色不会发生冲突..

 

  输出可行解就是遍历一次逆拓扑排序时染成的颜色..

  输出同一组颜色的解就是其中的一组可行解..

  

Tips:

  ※ 用双向链表..方便建反图..

  ※ 求强连通分量是把所有的点都遍历一遍..所以是2*n..

  ※ 建反图的时候是遍历所有的边..然后根据edge.from 和 edge.to 建图

  ※ 拓扑排序是对缩点后的有向无环图排序..找出一组可行解..

    每次拓扑排序找到一个解的时候..就把和他冲突的另外一个解也染色了..

  ※ 连边的时候连的是必须发生的两件事..

  ※ 如果求连通分量染色的时候遇到冲突事件在一个分量中出现则不能有可行解

     否则就把缩点后冲突事件记录起来..以便拓扑排序的时候染色..

  ※ 最后记录某一个颜色的可行解..

    然后遍历一遍1~n 找出该时间是否属于该可行解..属于就输出..不属于就输出对立的解..

 

总结:

2-sat问题是
  ①. 把有冲突的分成n组
  ②. 每组2个..然后根据冲突关系把没冲突的连边
  ③. 用tarjan染色..
  ④. 把缩点后的图建反图..
  ⑤. 根据反图拓扑排序
  ⑥. 拓扑排序过程中给其中一组解染色..同时给冲突的解染色
  ⑦. 根据第⑥.步找出可行解并输出..

 

Code:

View Code
  1 #include <stdio.h>
  2 #include <cstring>
  3 #include <fstream>
  4 #include <algorithm>
  5 using namespace std;
  6 #define clr(x) memset(x, 0, sizeof(x))
  7 const int INF = 0x1f1f1f1f;
  8 const int MAXN = 1010*2;
  9 
 10 struct Time
 11 {
 12     int st;
 13     int en;
 14     int la;
 15 }time[MAXN];
 16 
 17 struct Edge
 18 {
 19     int from;
 20     int next;
 21     int to;
 22 }edge[3000010], edge2[3000010];///!!!
 23 int head[MAXN], head2[MAXN];
 24 int tot, tot2;
 25 
 26 void add(int s, int u)
 27 {
 28     edge[tot].from = s;
 29     edge[tot].to = u;
 30     edge[tot].next = head[s];
 31     head[s] = tot++;
 32 }
 33 
 34 void add2(int s, int u)
 35 {
 36     edge2[tot2].to = u;
 37     edge2[tot2].next = head2[s];
 38     head2[s] = tot2++;
 39 }
 40 
 41 int low[MAXN], dfn[MAXN];
 42 int ins[MAXN], sta[MAXN], col[MAXN];
 43 int ti, top, cnt;
 44 
 45 void tarjan(int u)
 46 {
 47     int i, j, k;
 48     dfn[u] = low[u] = ++ti;
 49     sta[++top] = u;
 50     ins[u] = 1;
 51     for(i = head[u]; i != -1; i = edge[i].next) {
 52         k = edge[i].to;
 53         if(!dfn[k]) {
 54             tarjan(k);
 55             low[u] = min(low[u], low[k]);
 56         } else if(ins[k])
 57             low[u] = min(low[u], dfn[k]);
 58     }
 59     if(dfn[u] == low[u]) {
 60         cnt++;
 61         do
 62         {
 63             k = sta[top--];
 64             col[k] = cnt;
 65             ins[k] = 0;
 66         }while(k != u);
 67     }
 68 }
 69 
 70 int n;
 71 void solve_ta()
 72 {
 73     int i, j, k;
 74     ti = cnt = top = 0;
 75     clr(dfn);
 76     for(i = 1; i <= 2*n; ++i)
 77     if(!dfn[i])
 78         tarjan(i);
 79 }
 80 
 81 int ind[MAXN], res[MAXN];
 82 int q[MAXN];
 83 
 84 void make_G()
 85 {
 86     int i, j, k;
 87     tot2 = 0;
 88     memset(head2, 0xff, sizeof(head2));
 89     clr(ind);
 90     for(i = 0; i < tot; ++i) {///!!!!
 91         if(col[edge[i].from] != col[edge[i].to]) {
 92             add2(col[edge[i].to], col[edge[i].from]);
 93             ind[col[edge[i].from]]++;
 94         }
 95     }
 96 }
 97 
 98 int ccol[MAXN];
 99 int ans[MAXN], ct[MAXN];
100 void toposort()
101 {
102     int front = 0, rear = 0;
103     int i, k;
104     make_G();
105     top = 0;
106     clr(ccol);
107     for(i = 1; i <= cnt; i++)///!!
108         if(ind[i] == 0)
109             q[rear++] = i;
110     while(front < rear) {
111         int x = q[front++];
112         if(ccol[x] == 0) {
113             ccol[x] = 1;
114             ccol[ct[x]] = -1;
115         }
116         for(i = head2[x]; i != -1;i = edge2[i].next) {
117             k = edge2[i].to;
118             ind[k]--;
119             if(ind[k] == 0) {
120                 q[rear++] = k;
121             }
122         }
123     }
124 }
125 
126 int main()
127 {
128     int i, j, k;
129     int sh, sm, eh, em, d;///!!!
130     bool flag;
131    // freopen("e:\\acm\\mess\\stdin-stdout\\in.txt", "r", stdin);
132     while(scanf("%d", &n) != EOF)
133     {
134         tot = 0;
135         memset(head, 0xff, sizeof(head));
136         flag = false;
137 
138         for(i = 1; i <= n; ++i) {
139             scanf("%d:%d %d:%d %d", &sh, &sm, &eh, &em, &d);
140             time[i].st = sh*60+sm;
141             time[i].en = eh*60+em;
142             time[i].la = d;
143         }
144 
145         for(i = 1; i <= n; ++i)
146         for(j = 1; j <= n; ++j)
147             if(i != j) {
148                 /*
149                 if((time[i].st+time[i].la < time[j].st) || (time[i].st > time[j].st + time[j].la))
150                     add(i, j);
151                 if((time[i].en-time[i].la > time[j].st+time[j].la) || (time[i].en < time[j].st))
152                     add(i+n, j);
153                 if((time[i].st+time[i].la < time[j].en-time[j].la) || (time[i].st > time[j].en))
154                     add(i, j+n);
155                 if((time[i].en-time[i].la > time[j].en) || (time[i].en < time[j].en-time[j].la))
156                     add(i+n, j+n);
157                 */
158 
159                 if(time[i].st < time[j].st+time[j].la && time[j].st < time[i].st+time[i].la )
160                     add(i, j+n);
161                 if(time[i].st < time[j].en && time[j].en-time[j].la < time[i].st+time[i].la)
162                     add(i, j);
163                 if(time[i].en-time[i].la< time[j].st+time[j].la && time[j].st<time[i].en)
164                     add(i+n, j+n);
165                 if(time[i].en - time[i].la < time[j].en && time[j].en-time[j].la < time[i].en)
166                     add(i+n, j);
167             }
168 
169         solve_ta();
170         for(i = 1; i <= n; ++i) {
171             if(col[i] == col[i+n]) {
172                 flag = true;
173                 break;
174             }
175             ct[col[i]] = col[i+n];
176             ct[col[i+n]] = col[i];
177         }
178 
179 
180         if(flag) puts("NO");
181         else {
182             toposort();
183             clr(ans);
184 
185             for(i = 1; i <= 2*n; ++i)
186                 if(ccol[col[i]] == 1)
187                     ans[i] = 1;
188             puts("YES");
189             for(i = 1; i <= n; ++i) {
190                 if(ans[i]) printf("%02d:%02d %02d:%02d\n", time[i].st/60, time[i].st%60, (time[i].st+time[i].la)/60, (time[i].st+time[i].la)%60);
191                 else printf("%02d:%02d %02d:%02d\n", (time[i].en-time[i].la)/60, (time[i].en-time[i].la)%60, time[i].en/60, time[i].en%60);
192             }
193         }
194 
195     }
196     return 0;
197 }

 

题目链接:http://poj.org/problem?id=3683

转载于:https://www.cnblogs.com/Griselda/archive/2012/10/09/2716647.html

相关文章:

Matlab并行编程方法1

相信很多朋友在利用matlab进行计算时&#xff0c;会遇到循环次数过大&#xff0c;或者是单次计算量过大的问题&#xff0c;比如需要计算的数值阵列数据量过大&#xff0c;利用传统的编程方式&#xff0c;跑一次程序几个小时&#xff0c;都要等的急死了是不是呢&#xff1f;如果…

使用postman修改SAP Marketing Cloud contact主数据

Marketing Cloud里的contact主数据&#xff0c;创建成功后也不是所有字段都能够被修改。在Personal data区域的字段是可以被修改的。 比如我在“客户属性”字段里维护了一些值&#xff1a; 然后点保存&#xff1a; 其中第二个batch操作是通过一个roundtrip读取contact模型下多个…

java判断一个对象是否为空_Java中判断对象是否为空的方法的详解

首先来看一下工具StringUtils的判断方法&#xff1a;一种是org.apache.commons.lang3包下的&#xff1b;另一种是org.springframework.util包下的。这两种StringUtils工具类判断对象是否为空是有差距的&#xff1a;StringUtils.isEmpty(CharSequence cs); //org.apache.commons…

解决cocos2dx 3.x 导入cocostudio的ui界面出现错位问题

笔者今天发现导入cocostudio的ui界面时&#xff0c;会有部分控件出现错位的现象&#xff0c;后来我看了一下源码&#xff0c;发现是部分控件是没有继承 Layout类&#xff0c;导致不能设置控件位置造成&#xff0c;原因可以看看cocos2dx 源码的CCSGUIReader.cpp文件的函数&#…

Media Queries

支持情况罗列成如下表&#xff1a; Media Queries 使用 说起CSS3的新特性&#xff0c;就不得不提到 Media Queries 。 本文比较详细&#xff0c;所以很多实际中用不到。所以如果只是想简单了解Media Queries&#xff0c;推荐参考 CSS3 Media Queries 。 CSS2.1定义了 Media 的部…

AndroidStudio脚本命令指定AAR生成目录与版本号

A build.gradle全局常量&#xff1a; //根路径def ROOT_PATH rootProject.rootDir.pathdef GROUP "com.genialsir.mobileads"def MOB_SDK_VERSION_NAME "1.1.2" 复制代码 B 在当前库项目的build.gradle文件中android{}中配置如下&#xff1a; //自定义a…

文本文件 java_简单的用java实现读/写文本文件的示例

简单的用java实现读/写文本文件的示例更新时间&#xff1a;2008年07月26日 13:09:26 作者&#xff1a;同时也展示了如果从输入流中读出来内容写入输出流中(仅限文本流)三个例子可以独立存在&#xff0c;所以根据需要只看其中一个就行了。/** 简单的读/写文本文件的示例* 这里…

7个华丽的基于Canvas的HTML5动画

说起HTML5&#xff0c;可能让你印象更深的是其基于Canvas的动画特效&#xff0c;虽然Canvas在HTML5中的应用并不全都是动画制作&#xff0c;但其动画效果确实让人震惊。本文收集了7个最让人难忘的HTML5 Canvas动画&#xff0c;包括画板、文字、图表等&#xff0c;希望你会喜欢。…

网络工程师课程---4、网络层(网关是什么)

网络工程师课程---4、网络层&#xff08;网关是什么&#xff09; 一、总结 一句话总结&#xff1a; 必在当前网段&#xff1a;你到达另外一个网段必过的一个端口&#xff0c;所以必在当前网段 1、icmp如何检测双向通路的连通性&#xff1f; ping 命令 2、计算机1-65535这些端口…

团队分数分配方法——BY 李栋

作为一个团队&#xff0c;自然是一体的&#xff0c;所以要摒弃个人开发的不良习惯&#xff0c;互帮互助&#xff0c;共同进步。以期望在项目过程中能够不使一个人掉队&#xff0c;不因一个人的工作而使全队进度拖延。所以在分工的基础上还是要互帮互助&#xff0c;团队整体的分…

autowired java_Java 基础之Autowired 是否是自动注入

Java 基础之Autowired 是否是自动注入相信很多人对Autowired 注解理解不深入&#xff0c;或者是认为此注解就是spring的自动注入。相信看完本篇文章&#xff0c;你会有更加不一样的理解。首先我们先看下什么是手动注入&#xff1f;在我们的spring应用程序中&#xff0c;定义多个…

Eclipse进行可视化的GUI开发3大GUI插件

Eclipse进行可视化的GUI开发3大GUI插件 转自http://www.cnblogs.com/NationWoo/archive/2011/05/31/2065176.htmlEclipse并不自带GUI的可视化开发工具&#xff0c;那么如果要在Eclipse进行可视化的GUI开发&#xff0c;就需要依靠第三方的插件。 1. Visual Editor Eclipse官方提…

【BZOJ 4016】[FJOI2014]最短路径树问题

&#xff01; 卡时过了 为什么我的这么慢&#xff1f;姿势不对&#xff1f;&#xff1f;&#xff1f; -->谢 ws_fqk 我的Do&#xff08;num[i]&#xff09;应该用 DO(root) 找了半天的root居然没有用.... define的教训永远忘不了了&#xff01;&#xff01;&#xff01; 优化…

mongodb索引--从55.7秒到毫秒级别

从头开始&#xff0c;验证mongodb的索引的好处。(window7环境下) 下载mongodb服务器&#xff0c;并解压到d盘&#xff0c;并使用以下命令启动 mongod --dbpath D:\mongodb\datamongo客户端Robo 3T 去官网下载&#xff0c;安装准备数据&#xff0c;条数为1亿public static void …

汉字转16进制java_java实现汉字转unicode与汉字转16进制实例

本文实例讲述了java实现汉字转unicode与汉字转16进制的实现方法。分享给大家供大家参考。具体实现方法如下&#xff1a;一、汉字转unicodepublic static String toUnicode(String s){String as[] new String[s.length()];String s1 "";for (int i 0; i < s.len…

使用pytest对django项目单元测试

2019独角兽企业重金招聘Python工程师标准>>> 背景 使用django开发了个人博客&#xff0c;欲单元测试&#xff0c;后遍寻网络&#xff0c;然相关资料甚少&#xff0c;遂成此文&#xff0c;望对汝有所助 环境 pytestpytest-djangopytest-covpytest-htmldjangomixer测试…

jquery通知插件toastr

使用方法3个简单步骤对于其他API调用,看到演示。<link href"toastr.css" rel"stylesheet"/> <script src"toastr.js"></script> //显示一个信息没有标题 toastr.info(Are you the 6 fingered man?)其他选项/显示一个警告,没有…

1282. Game Tree

http://acm.timus.ru/problem.aspx?space1&num1282 简单博弈 注意题意的理解 代码&#xff1a; #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<vector> #include<queue> #include<map> #i…

java web dao_JavaWeb项目,DAO应该怎么写?

有一张字段足够多的表&#xff0c;要对它进行各种各样的查询&#xff1a;根据字段A根据字段B&#xff0c;或者根据字段A和B&#xff0c;或者再加上字段C&#xff0c;然后可能还要加上分页&#xff0c;排序等等的逻辑。现在的项目的DAO层为了满足上面这些需要出现了很多参数列表…

2016 - 1- 21 - RunLoop使用(2016-1-24修改一次)(2016 - 1 - 24 再次修改)

一&#xff1a;常驻线程 &#xff1a;当需要一个线程一直处理一些耗时操作时&#xff0c;可以让它拥有一个RunLoop。具体代码如下&#xff1a; 1.通过给RunloopMode里加源来保证RunLoop不直接退出。 这里有个很重要得知识点&#xff0c;runloop对象如果mode为空得话&#xff…

【BZOJ1016】【Luogu P4208】 [JSOI2008]最小生成树计数 最小生成树,矩阵树定理

蛮不错的一道题&#xff0c;遗憾就遗憾在数据范围会导致暴力轻松跑过。 最小生成树的两个性质&#xff1a; 不同的最小生成树&#xff0c;相同权值使用的边数一定相同。不同的最小生成树&#xff0c;将其都去掉同一个权值的所有边&#xff0c;其连通性一致。这样我们随便跑一个…

Asterisk安装

一、获取asterisk安装包wget http://downloads.asterisk.org/pub/telephony/asterisk/releases/asterisk-1.6.0.tar.gz后面的版本号可以改变&#xff0c;可以安装的版本可以参考http://downloads.asterisk.org/pub/telephony/asterisk/releases/二、解压安装1. [root~]# tar -z…

java编写一个通讯录_java写的通讯录(小玩意)

上次有发个超级菜鸟级别的连接access的小程序受兄弟委托&#xff0c;如今表妹期末了&#xff0c;要写个通讯录于是草草的给写了个&#xff0c;毕竟有一个学期了&#xff0c;所以这次的代码会比较合理些……使用说明:实现技术:java语言,界面采用java swing编程,数据库用access数…

20175203 2018-2019 实验五《网络编程与安全》

20175203 2018-2019 实验五《网络编程与安全》 知识重点&#xff08;摘自实验资料&#xff09; 栈 &#xff1a;(Stack)是一种只允许在表尾插入和删除的线性表&#xff0c;有先进后出&#xff08;FILO&#xff09;&#xff0c;后进先出(LIFO)的特点。允许插入和删除的一端称为栈…

统计文件种类数+获取子shell返回值的其它方法

前言 只是作为一个shell的小小练习和日常统计用&#xff0c;瞎折腾的过程中也是摸到了获取子shell返回值的几种方法&#xff1b; 肯定还有别的方法&#xff0c;跟进程间的通信相关&#xff0c;希望你能提出建议和补充&#xff0c;谢谢~ 完整程序&#xff1a; #! /bin/bash #检查…

java中next的用法_关于java iterator的next()方法的用法

UYOUnext()是java迭代器类(Iterator)的方法&#xff0c;获得当前游标指向的下一个元素&#xff0c;详细说明和应用如下&#xff1a;1、迭代器(Iterator)介绍  迭代器是一种设计模式&#xff0c;它是一个对象&#xff0c;它可以遍历并选择序列中的对象&#xff0c;而开发人员不…

Python如何进行cross validation training

以4-fold validation training为例 (1) 给定数据集data和标签集label 样本个数为 sampNum len(data)(2) 将给定的所有examples分为10组 每个fold个数为 foldNum sampNum/10 (3) 将给定的所有examples分为10组 参考scikit-learn的3.1节&#xff1a;Cross-validation 1 impor…

Python的while循环

2019独角兽企业重金招聘Python工程师标准>>> 1.while循环的格式 while 条件:条件满足时&#xff0c;做的事情1条件满足时&#xff0c;做的事情2条件满足时&#xff0c;做的事情3...(省略)...demo i 0while i < 5:print("当前是第%d次执行循环" % (i …

LeetCode Add Binary

Given two binary strings, return their sum (also a binary string). For example,a "11"b "1"Return "100". 这题用数组来做可能更简单&#xff0c;但考虑到可能面试的时候要求不能开额外的数组&#xff0c;就只能对string操作了。最主要的…

linux java内存分析_Java内存分析利器MAT使用详解

这是一篇阅读MAT helper的笔记。Heap dump是Java进程在特定时间的一个内存快照。通常在触发heap dump之前会进行一次full gc&#xff0c;这样dump出来的内容就包含的是被gc后的对象。dump文件包含的内容&#xff1a;1&#xff0c;全部的对象&#xff1a;类&#xff0c;域&#…