这是我遇到的第一道2-SAT问题。将两条边记为x和y。如果x和y相交,那么x和y不能同时在环外(即都取true),也不能同时在环内(即都取false)。前者,我们有x->~y, y -> ~x;后者,我们有~x->y, ~y -> x。

这道题只问2-SAT是否能满足,而没有问怎样才能满足,所以只需要求强连通子图部分,而不需要逆向拓扑排序部分(这部分目前还不是很懂)。

thestoryofsnow 3207 Accepted 1236K 79MS C++ 3532B
/*
ID: thestor1
LANG: C++
TASK: poj3207
*/
#include <iostream>
#include <fstream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <limits>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <cassert>using namespace std;// const int MAXN = 1000;
const int MAXM = 500;class Edge
{
public:int a, b;Edge() {}Edge(int a, int b) : a(a), b(b) {}inline bool operator< (const Edge &rhs) const {return a < rhs.a || (a == rhs.a && b < rhs.b);}
};bool isundefined(int u, vector<int> &indexes)
{return indexes[u] < 0;
}void strongconnect(int u, int &index, vector<int> &indexes, vector<int> &lowlinks, int &SCCNO, vector<int> &sccnos, stack<int> &S, vector<bool> &onStack, const vector<vector<int> > &adjs)
{// Set the depth index for u to the smallest unused indexindexes[u] = index;lowlinks[u] = index;index++;S.push(u);onStack[u] = true;// Consider successors of ufor (int i = 0; i < adjs[u].size(); ++i){int v = adjs[u][i];if (isundefined(v, indexes)){// Successor v has not yet been visited; recurse on itstrongconnect(v, index, indexes, lowlinks, SCCNO, sccnos, S, onStack, adjs);lowlinks[u] = min(lowlinks[u], lowlinks[v]);}else if (onStack[v]){// Successor v is in stack S and hence in the current SCClowlinks[u] = min(lowlinks[u], lowlinks[v]);    }}// If u is a root node, pop the stack and generate an SCCif (indexes[u] == lowlinks[u]){// start a new strongly connected componentwhile (true){int v = S.top();S.pop();onStack[v] = false;// add v to current strongly connected componentsccnos[v] = SCCNO;if (v == u){break;}}SCCNO++;}
}// Tarjan's strongly connected components algorithm
// See http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
void tarjan(const int N, const vector<vector<int> > &adjs, int &SCCNO, vector<int> &sccnos)
{int index = 0;vector<int> indexes(N, -1);vector<int> lowlinks(N, -1);stack<int> S;vector<bool> onStack(N, false);for (int u = 0; u < N; ++u){if (isundefined(u, indexes)){strongconnect(u, index, indexes, lowlinks, SCCNO, sccnos, S, onStack, adjs);}}}int main()
{int n, m;scanf("%d%d", &n, &m);Edge edges[MAXM];for (int i = 0; i < m; ++i){scanf("%d%d", &edges[i].a, &edges[i].b);if (edges[i].a > edges[i].b){int t = edges[i].a;edges[i].a = edges[i].b;edges[i].b = t;}}sort(edges, edges + m);// in the 2-SAT sense, if i is x, then i + n is ~xvector<vector<int> > adjs(2 * m, std::vector<int>());for (int i = 0; i < m; ++i){for (int j = i + 1; j < m && edges[j].a < edges[i].b; ++j){if (edges[j].b > edges[i].b){// i interleaves with j, then x (i) and y (j) can not both be true// then if x is true, y should be false (that is, ~y is true)//  x -> ~yadjs[i].push_back(j + m);adjs[j].push_back(i + m);adjs[i + m].push_back(j);adjs[j + m].push_back(i);    }}}int SCCNO = 0;vector<int> sccnos(2 * m, -1);tarjan(2 * m, adjs, SCCNO, sccnos);bool conflict = false;for (int i = 0; i < m; ++i){// if both x and ~x are true, we have conflicts hereif (sccnos[i] == sccnos[i + m]){conflict = true;break;}}if (conflict){printf("the evil panda is lying again\n");}else{printf("panda is telling the truth...\n");}return 0;
}

POJ 3207 解题报告相关推荐

  1. POJ 1003 解题报告

    1.问题描述: http://poj.org/problem?id=1003 2.解题思路: 最直观的的想法是看能不能够直接求出一个通项式,然后直接算就好了, 但是这样好水的样子,而且也不知道这个通项 ...

  2. POJ 2159 解题报告

    一.substitution cipher (置换密码): Substitution cipher changes all occurrences of each letter to some oth ...

  3. POJ 3250 解题报告 Bad Hair Day (单调栈)

    传送门:http://poj.org/problem?id=3250 这题--水题啊,单调栈可解. 上一波C艹实现 #include <iostream> #include <cst ...

  4. poj 2262 解题报告

    这道题是给一个偶数,然后找出两个素数的a.b和等于这个偶数,如果有多对的话就输出一个a-b最大的组结果.这道题很简单以前AC过,今天我改了一些判断一个数是否是素数的那个方法,但是没想到时间还是和以前的 ...

  5. POJ 1679 解题报告

    这道题是判断最小生成树是否唯一. 方法之一(也是显而易见正确的方法)是求次小生成树,然后看两者的值是否一样.一样则不唯一.ByVoid有对次小生成树(及次短路径)的讲解(https://www.byv ...

  6. POJ 1185 解题报告 炮兵阵地

    题目是中文的,我就不描述题意了. 题目用到的主要算法是状态压缩dp. 思路是,我们要知道n行最多的炮数,只要知道n-2行所有状态最多的炮数,就可以根据n-1行和n行最多可行的状态算出.也就是说,n-2 ...

  7. POJ 2593解题报告

    题目来源 :PKU 2593 http://acm.pku.edu.cn/JudgeOnline/problem?id=2593 解法类型 :动态规划应用 作    者 :刘亚宁 题目大意: 抽取一个 ...

  8. POJ 1017解题报告

    这题看起来简单,实际上要考虑的地方不少,一不小心就可能漏掉某条件导致WA,我一次测了1000组输入输出才发现自己原来的代码里面有40组输出是错误的,然后一步步调试,终于AC了.一直WA又找不到自己错在 ...

  9. 解题报告 poj 3207

    1.        题目 POJ 3207 2.        题目实质 平面上,一个圆,圆的边上按顺时针放着n个点.现在要连m条边,比如a,b,那么a到b可以从圆的内部连接,也可以从圆的外部连接.问 ...

  10. POJ 2800 垂直直方图 解题报告

    POJ 2800 垂直直方图 解题报告 编号:2800   考查点:简单计算题 思路: 用gets()读入4行数据,然后按字符统计,显示的时候有点小处理即可. 提交情况: 感觉POJ的测试数据有点骗人 ...

最新文章

  1. 力扣(LeetCode)刷题,简单题(第25期)
  2. Android.mk文件语法规范及使用模板 (转载)
  3. main方法的格式讲解
  4. 文远知行A轮再获数千万美元融资 商汤科技和农银国际跟投
  5. 【python】队列——用链表实现队列操作
  6. android: 发送自定义广播
  7. 软考考前注意事项及答题技巧
  8. boost::posix_time模块实现本地时间和 UTC 之间的转换的测试程序
  9. windows下php swoole扩展,Windows 下安装 swoole 图文教程(php)
  10. windows qt 不能debug_linux配置vlc-qt
  11. python做大屏数据可视化_超强大!Python 可视化这款大屏就够了!
  12. string转map集合_集合(下)
  13. DownloadManager不好用?试试ZlsamDownloadService
  14. java假设模拟请求重新启动路由器(网络爬虫经常使用),还有java怎样下载图片
  15. 【在线课件制作软件】Focusky教程 | 导出PDF并打印
  16. 职业学校计算机教学,职业学校计算机专业教学初探
  17. 一位博士在华为的 22 年(干货满满)
  18. 【Lintcode】1132. Valid Triangle Number
  19. 《MATLAB 神经网络43个案例分析》:第34章 广义神经网络的聚类算法——网络入侵聚类
  20. Elasticsearch:集群配置及异常解决

热门文章

  1. 华为2019届校招笔试题
  2. win10计算机分盘怎么设置密码,Win10如何限制磁盘分区被访问 Win10自带磁盘加密功能BitLocker在哪里...
  3. 视频怎么制作动图?教你一招视频gif制作的方法
  4. 计算机绘图中常用指令,【CAD快捷键运用】CAD常用命令汇总
  5. 每日方法分享:手机识别图片文字怎么弄?
  6. python文件管理api_python调用有道智云API实现文件批量翻译
  7. Spring Boot 对接微信V3支付(附源码)
  8. 爬取汽车之家所有车型,价格,配置
  9. 获取GooglePlay下载来源广告数据统计接入
  10. mxh缩写英语_mxh的含义,mxh是什么的缩写,mxh的词语,mxh代表的意思