地址 https://algospot.com/judge/problem/read/MEETINGROOM

解答  2-sat 代码样例过了 没有ac。 我又没有正确代码对拍。。。。。

已确认是输出问题 修改完成

  1. #include <algorithm>
  2. #include <iostream>
  3. #include <vector>
  4. #include <stack>
  5.  
  6. using namespace std;
  7.  
  8. vector<vector<int>> adj;
  9.  
  10. vector<int> sccId, discovered, finished;
  11. stack<int> st; //保存顶点序号的栈
  12. int sccCounter, vertexCounter;
  13.  
  14. //返回以here为根节点的子树中
  15. //能够到达后向边的最小发现顺序
  16. int scc(int here) {
  17. int ret = discovered[here] = vertexCounter++;
  18. //将here存入栈,here的所有后代节点都会在here之后进栈
  19. st.push(here);
  20.  
  21. for (int i = ; i < adj[here].size(); ++i) {
  22. int there = adj[here][i];
  23. //(here,there)是树边
  24. if (discovered[there] == -)
  25. ret = min(ret, scc(there));
  26. else if (discovered[there] < discovered[here] && finished[there] != )
  27. ret = min(ret, discovered[there]);
  28. }
  29.  
  30. //判断here是否为强联通分量的根节点
  31. if (ret == discovered[here]) {
  32. //以here为根节点的子树中,将剩余所有顶点全部绑定为同一分量
  33. while (true) {
  34. int t = st.top();
  35. st.pop();
  36. sccId[t] = sccCounter;
  37. if (t == here) break;
  38. }
  39. ++sccCounter;
  40. }
  41.  
  42. finished[here] = ;
  43. return ret;
  44. }
  45.  
  46. //tarjan 的scc算法
  47. vector<int> tarjanSCC() {
  48. //数组和计数器的初始化
  49. sccId = discovered = finished = vector<int>(adj.size(), -);
  50. sccCounter = vertexCounter = ;
  51.  
  52. //对所有顶点调用scc()
  53. for (int i = ; i < adj.size(); ++i)
  54. if (discovered[i] == -) scc(i);
  55. return sccId;
  56. }
  57.  
  58. //========================================================================
  59. //图的领接表表示法
  60. //vector<vector<int>> adj;
  61.  
  62. bool disjoint(const pair<int, int>& a, const pair<int, int>& b) {
  63. return a.second <= b.first || b.second <= a.first;
  64. }
  65.  
  66. //如果meetings[]表示各队提出的开会时间
  67. //则将此题转换为2-SAT问题后生成蕴含图
  68. //第i个团队需要选择meetings[2*i]或meetings[2*i+1]时候之一开会
  69. void makeGraph(const vector<pair<int, int>>& meetings)
  70. {
  71. int vars = meetings.size();
  72.  
  73. //每个变量对应图的两个顶点
  74. adj.clear(); adj.resize(vars * );
  75. for (int i = ; i < vars; i += ) {
  76. //各团队需要选择第i号和第j号会议之一
  77. //添加(i or j )句子
  78. int j = i + ;
  79. adj[i * + ].push_back(j * );
  80. adj[j * + ].push_back(i * );
  81. }
  82.  
  83. for (int i = ; i < vars; ++i) {
  84. for (int j = ; j < i; ++j) {
  85. //第i号会议和第j号会议重叠
  86. if (!disjoint(meetings[i], meetings[j])) {
  87. //放弃第i个会议 或者放弃第j个会议
  88. //添加 (~i or ~j)子句
  89. adj[i * ].push_back(j * + );
  90. adj[j * ].push_back(i * + );
  91. }
  92. }
  93. }
  94. }
  95.  
  96. vector<int> solve2SAT()
  97. {
  98. int n = adj.size() / ;
  99. vector<int> label = tarjanSCC();
  100.  
  101. for (int i = ; i < * n; i += )
  102. if (label[i] == label[i + ])
  103. return vector<int>();
  104.  
  105. vector<int> value( * n, -);
  106.  
  107. vector<pair<int, int>> order;
  108. for (int i = ; i < * n; i++)
  109. order.push_back(make_pair(label[i], i));
  110. sort(order.begin(), order.end());
  111.  
  112. for (int i = ; i < * n; ++i) {
  113. int vertex = order[i].second;
  114. int variable = vertex / , isTrue = vertex % ;
  115. if (value[variable] != -) continue;
  116. value[variable] = !isTrue;
  117. }
  118. return value;
  119. }
  120.  
  121. int main()
  122. {
  123. int n;
  124. cin >> n;
  125.  
  126. while (n--) {
  127. int m;
  128. cin >> m;
  129. vector<pair<int, int>> meetings;
  130. while (m--) {
  131. int a, b, c, d;
  132. cin >> a >> b >> c >> d;
  133. meetings.push_back(make_pair(a, b));
  134. meetings.push_back(make_pair(c, d));
  135. }
  136. makeGraph(meetings);
  137.  
  138. vector<int> v = solve2SAT();
  139. if (v.empty()) {
  140. cout << "IMPOSSIBLE" << endl;;
  141. }
  142. else {
  143. cout << "POSSIBLE" << endl;
  144. for (int i = ; i < v.size()/; i+=) {
  145. if (v[i] == ) {
  146. cout << meetings[i].first << ' ' << meetings[i].second << endl;
  147. }
  148. else {
  149. cout << meetings[i+].first << ' ' << meetings[i+].second << endl;
  150. }
  151. }
  152. }
  153. }
  154.  
  155. return ;
  156. }

一份tarjan 模板

  1. // 11111111.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
  2. //
  3.  
  4. #include "pch.h"
  5. #include <iostream>
  6. #include <vector>
  7. #include <stack>
  8. #include <algorithm>
  9.  
  10. using namespace std;
  11.  
  12. const int maxn = 2e5 + ;
  13. vector<int> E[maxn];
  14. int vis[maxn];
  15. int dfn[maxn], low[maxn], tot, n, ans = maxn;
  16. stack<int> s;
  17.  
  18. void tarjan(int x)
  19. {
  20. low[x] = dfn[x] = ++ tot;
  21. s.push(x); vis[x] = ;
  22.  
  23. for (int i = ; i < E[x].size(); i++) {
  24. int v = E[x][i];
  25. if (!dfn[v]) {
  26. tarjan(v);
  27. low[x] = min(low[x], low[v]);
  28. }
  29. else if (vis[v]) {
  30. low[x] = min(low[x], dfn[v]);
  31. }
  32. }
  33.  
  34. if (low[x] == dfn[x]) {
  35. int cnt = ;
  36. while () {
  37. int now = s.top();
  38. s.pop();
  39. vis[x] = ;
  40. cnt++;
  41. if (now == x) break;
  42. }
  43. if (cnt > ) ans = min(ans, cnt);
  44. }
  45.  
  46. }
  47.  
  48. int main()
  49. {
  50. scanf("%d",&n );
  51. for (int i = ; i <= n; i++) {
  52. int x;
  53. scanf("%d", &x);
  54. E[i].push_back(x);
  55. }
  56.  
  57. for (int i = ; i <= n; i++) {
  58. if (!dfn[i])
  59. tarjan(i);
  60. }
  61.  
  62. cout << ans << endl;
  63.  
  64. return ;
  65. }

tarjan模板

算法问题实战策略 MEETINGROOM 附一份tarjan模板的更多相关文章

  1. 算法问题实战策略 PICNIC

    下面是另一道搜索题目的解答过程题目是<算法问题实战策略>中的一题oj地址是韩国网站 连接比较慢 https://algospot.com/judge/problem/read/PICNIC ...

  2. 《算法问题实战策略》-chaper7-穷举法

    关于这一章节<算法实战策略>有一段概述问题,我认为对于编程人员来说非常有价值,故在这里进行如下的摘抄: 构想算法是很艰难的工作.相比大家都经历过,面对复杂的要求只是傻乎乎地盯着显示器,或者 ...

  3. 《算法问题实战策略》-chaper32-网络流

    基本的网络流模型: 在图论这一块初步的应用领域中,两个最常见的关注点,其一时图中的路径长度,也就是我们常说的的最短路径问题,另一个则是所谓的“流问题”. 流问题的基本概念: 首先给出一张图. 其实所谓 ...

  4. 《算法问题实战策略》-chaper13-数值分析

    这一章节主要介绍我们在进行数值分析常用的二分.三分和一个近似求解区间积分的辛普森法. 首先介绍二分. 其实二分的思想很好理解并且笔者在之前的一些文章中也有所渗透,对于二次函数甚至单元高次函数的零点求解 ...

  5. 《算法问题实战策略》——chaper9——动态规划法技巧

    Q1: 数字游戏: 两个人(A.B)用n个整数排成的一排棋盘玩游戏,游戏从A开始,每个人有如下操作: (1)    拿走棋盘最右侧或者最左侧的棋子,被拿走的数字从棋盘中抹掉. (2)    棋盘中还剩 ...

  6. 《算法问题实战策略》-chaper8-动态规划法

    Q1:偶尔在电视上看到一些被称为“神童”的孩子们背诵小数点以后几万位的圆周率.背诵这么长的数字,可利用分割数字的方法.我们用这种方法将数字按照位数不等的大小分割后再背诵. 分割形式如下: 所有数字都相 ...

  7. 《算法问题实战策略》-chaper21-树的实现和遍历

    这一章节开始介绍一个数据结构中的一个基本概念——树. 我们从数据结构的解读来解释树结构的重要性,现实世界的数据除了最基本的线性结构(我们常用队列.数组和链表等结构表征),还有一个重要的特性——层级结构 ...

  8. 算法问题实战策略 QUADTREE

    地址 https://algospot.com/judge/problem/read/QUADTREE 将压缩字符串还原后翻转再次压缩的朴素做法 在数据量庞大的情况下是不可取的 所以需要在压缩的情况下 ...

  9. 算法问题实战策略 DICTIONARY

    地址 https://algospot.com/judge/problem/read/DICTIONARY 解法 构造一个26字母的有向图 判断无回路后 就可以输出判断出来的字符序了 比较各个字母的先 ...

随机推荐

  1. win10下配置python环境变量(Python配置环境变量)

    从官网下载Windows下的python版本,一路按照默认进行安装. 安装之后配置环境变量的步骤如下: 1,点“我的电脑”,右键选“属性”. 2,选择“高级系统设置”--->选“环境变量”--- ...

  2. 海康Poe 摄像头尾线与8根网线连接方法

    家里海康POE摄像头铜丝断了一根,拆开自己接了个RJ44座,线序黑. 棕. 绿. 橙. 红. 黄. 紫. 蓝 以此 对应橙白.橙.绿白.蓝.蓝白.绿.棕白.棕经测试无误,可以正常使用

  3. druid链接数据库

    所用jar包 commons-beanutils-1.8.0.jarcommons-logging-1.1.3.jardruid-1.0.9.jarmysql-connector-java-5.1.1 ...

  4. diango创建一个app

    创建一个app terminal里执行命令 python manage.py startapp app名称 注册 settings配置 INSTALLED_APPS = [ 'app01', 'app ...

  5. linux 磁盘分区和挂载看这一篇就够了

    Linux fdisk 和 mount 命令操作指南,linux磁盘管理.新增磁盘.挂载新硬盘(linux运维入门) 首先列出文件系统的整体磁盘空间使用情况.可以用来查看磁盘已被使用多少空间和还剩余多 ...

  6. java基础 - 形参和实参,值传递和引用传递

    形参和实参 形参:就是形式参数,用于定义方法的时候使用的参数,是用来接收调用者传递的参数的. 形参只有在方法被调用的时候,虚拟机才会分配内存单元,在方法调用结束之后便会释放所分配的内存单元. 因此,形 ...

  7. C#添加错误日志信息

    错误日志是软件用来记录运行时出错信息的文本文件.编程人员和维护人员等可以利用错误日志对系统进行调试和维护. 系统日志 系统日志包含了由Windows系统组件记录的事件.例如,在启动期间装入驱动程序或其 ...

  8. 指定节点滚动到屏幕中间的js

    父节点的class是slimScrollDiv 子节点的class是fa-warning 执行这个js document.getElementsByClassName("slimScroll ...

  9. css实现左右两个div等高

    提出问题: 现在有两个div,但是两个div里面内容多少不确定,可能左边多,可能右边多,css要如何设置可以保证左右两边的div等高呢? 解决方案: 每个div使用display:table-cell ...

  10. SpringBoot系列——Filter 过滤器

    前言 本文记录一下在SpringBoot项目中是如何使用Filter过滤器 代码.测试 Filter过滤器是servlet包下面的东西,因此我们不需要再额外引包 方法一 直接实现Filter接口,并使 ...