传送门

几乎和这个题一样,就不说题意了,比较特殊的点就是,这里有个结论:

  • 平面图的边数\(m<3n-6\),\(n\)为点数。

所以我们可以通过这个减枝,\(m\)较大时直接输出\(no\)。小范围直接上\(2-sat\)判断是否可行就行。

代码如下:

/*
* Author: heyuhhh
* Created Time: 2019/11/29 18:38:08
*/
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <iomanip>
#include <cstring>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
//#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 10005; int n, m;
int a[N], b[N], c[N]; vector<int> G[N], rG[N], vs;
int used[N], bel[N]; void adde(int from, int to) {
G[from].push_back(to);
rG[to].push_back(from);
} void dfs(int v) {
used[v] = true;
for(int i = 0; i < sz(G[v]); i++) {
int u = G[v][i];
if(!used[u])
dfs(u);
}
vs.push_back(v);
} void rdfs(int v, int k) {
used[v] = true;
bel[v] = k;
for(int i = 0; i < sz(G[v]); i++) {
int u = G[v][i];
if(!used[u])
rdfs(u, k);
}
} int scc() {
memset(used, 0, sizeof(used));
vs.clear();
for(int v = 1; v <= 2 * m; ++v)
if(!used[v]) dfs(v);
memset(used, 0, sizeof(used));
int k = 0;
for(int i = (int) vs.size() - 1; i >= 0; --i)
if(!used[vs[i]]) rdfs(vs[i], k++);
return k;
} bool cross(int x, int y) {
if(a[x] < a[y] && b[x] > a[y] && b[x] < b[y]) return true;
if(a[x] < b[y] && a[x] > a[y] && b[x] > b[y]) return true;
return false;
} void run(){
cin >> n >> m;
for(int i = 1; i <= m; i++) {
cin >> a[i] >> b[i];
}
for(int i = 1; i <= n; i++) {
int x; cin >> x;
c[x] = i;
}
if(m > 3 * n - 6) {
cout << "NO" << '\n';
return;
}
for(int i = 1; i <= 2 * m; i++) {
G[i].clear(); rG[i].clear();
}
for(int i = 1; i <= m; i++) {
a[i] = c[a[i]], b[i] = c[b[i]];
if(a[i] > b[i]) swap(a[i], b[i]);
}
for(int i = 1; i <= m; i++) {
for(int j = i + 1; j <= m; j++) {
if(cross(i, j)) {
adde(2 * i, 2 * j - 1);
adde(2 * i - 1, 2 * j);
adde(2 * j, 2 * i - 1);
adde(2 * j - 1, 2 * i);
}
}
}
scc();
for(int i = 1; i <= m; i++) {
if(bel[2 * i] == bel[2 * i - 1]) {
cout << "NO" << '\n';
return;
}
}
cout << "YES" << '\n';
} int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
int T; cin >> T;
while(T--) run();
return 0;
}

【bzoj1997】[Hnoi2010]Planar(平面图+2-sat)的更多相关文章

  1. [BZOJ1997][Hnoi2010]Planar 2-sat (联通分量) 平面图

    1997: [Hnoi2010]Planar Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 2317  Solved: 850[Submit][Stat ...

  2. [bzoj1997][Hnoi2010]Planar(2-sat||括号序列)

    开始填连通分量的大坑了= = 然后平面图有个性质m<=3*n-6..... 由平面图的欧拉定理n-m+r=2(r为平面图的面的个数),在极大平面图的情况可以代入得到m=3*n-6. 网上的证明( ...

  3. bzoj千题计划231:bzoj1997: [Hnoi2010]Planar

    http://www.lydsy.com/JudgeOnline/problem.php?id=1997 如果两条边在环内相交,那么一定也在环外相交 所以环内相交的两条边,必须一条在环内,一条在环外 ...

  4. BZOJ1997 [Hnoi2010]Planar (2-sat)

    题意:给你一个哈密顿图,判断是不是平面图 思路:先找出哈密顿图来.哈密顿回路可以看成一个环,把边集划分成两个集合,一个在环内,一个在外.如果有两条相交边在环内,则一定不是平面图,所以默认两条相交边,转 ...

  5. BZOJ1997 [Hnoi2010]Planar 【2-sat】

    题目链接 BZOJ1997 题解 显然相交的两条边不能同时在圆的一侧,\(2-sat\)判一下就好了 但这样边数是\(O(m^2)\)的,无法通过此题 但是\(n\)很小,平面图 边数上界为\(3n ...

  6. bzoj1997: [Hnoi2010]Planar

    2-SAT. 首先有平面图定理 m<=3*n-6,如果不满足这条件肯定不是平面图,直接退出. 然后构成哈密顿回路的边直接忽略. 把哈密顿回路当成一个圆, 如果俩条边交叉(用心去感受),只能一条边 ...

  7. bzoj1997 [Hnoi2010]Planar——2-SAT

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1997 神奇的经典2-SAT问题! 对于两个相交的区间,只能一里一外连边,所以可以进行2-SA ...

  8. bzoj1997 [HNOI2010]平面图判定Plana

    bzoj1997 [HNOI2010]平面图判定Planar 链接 bzoj luogu 思路 好像有很多种方法过去.我只说2-sat 环上的边,要不在里面,要不在外边. 有的边是不能同时在里面的,可 ...

  9. 【BZOJ1997】[Hnoi2010]Planar 2-SAT

    [BZOJ1997][Hnoi2010]Planar Description Input Output Sample Input 2 6 9 1 4 1 5 1 6 2 4 2 5 2 6 3 4 3 ...

  10. BZOJ 1997: [Hnoi2010]Planar( 2sat )

    平面图中E ≤ V*2-6.. 一个圈上2个点的边可以是在外或者内, 经典的2sat问题.. ----------------------------------------------------- ...

随机推荐

  1. SQL server利用脚本添加链接服务器,可设置别名

    USE [master]GO EXEC master.dbo.sp_addlinkedserver @server = N'你的别名', @srvproduct=N'', @provider=N'SQ ...

  2. 迁移文件是报错 django.db.utils.InternalError: (1054, "Unknown column 'name' in 'django_content_type'")

    相信大家在做django迁移时有可能会遇到这样的错误- django.db.utils.InternalError: (1054, “Unknown column ‘name’ in ‘django_ ...

  3. Python添加邮件附件并通过邮件发送测试报告

    import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText c ...

  4. 在 VS 中查看所有线程

    查看当前所有线程 在程序中打断点,然后启动调试(注意:线程窗口需要启动调试才可以看得到)点击 Debug > Windows > Threads 线程窗口如下:

  5. licode(1) Basic Example 客户端解析

    整体 在浏览其中输入https://dst_host_domain:13004后, 请求了index.html,该文件在licode\extras\basic_example\public\index ...

  6. AcWing 34. 链表中环的入口结点

    习题地址 https://www.acwing.com/problem/content/description/86/ 题目描述给定一个链表,若其中包含环,则输出环的入口节点. 若其中不包含环,则输出 ...

  7. Mybatis----传入参数parameterType类型详解

    Mybatis----传入参数parameterType类型详解 前言 Mybatis的Mapper文件中的select.insert.update.delete元素中有一个parameterType ...

  8. python-openCV 绘制图形

    文档链接:https://docs.opencv.org/trunk/dc/da5/tutorial_py_drawing_functions.html 文档描述了OpenCV的几个绘图功能: 绘制圆 ...

  9. Windows下怎么执行shell脚本

    1.在windows下想要执行shell脚本,需要使用到"Git Bash",所以我们需要先安装Git. 2.查看Git环境变量是否配置,没有配置需要配置(我这里安装Git时自动配 ...

  10. ros相关笔记

    catkin_make不编译某些package https://answers.ros.org/question/54181/how-to-exclude-one-package-from-the-c ...