【bzoj1997】[Hnoi2010]Planar(平面图+2-sat)
几乎和这个题一样,就不说题意了,比较特殊的点就是,这里有个结论:
- 平面图的边数\(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)的更多相关文章
- [BZOJ1997][Hnoi2010]Planar 2-sat (联通分量) 平面图
1997: [Hnoi2010]Planar Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 2317 Solved: 850[Submit][Stat ...
- [bzoj1997][Hnoi2010]Planar(2-sat||括号序列)
开始填连通分量的大坑了= = 然后平面图有个性质m<=3*n-6..... 由平面图的欧拉定理n-m+r=2(r为平面图的面的个数),在极大平面图的情况可以代入得到m=3*n-6. 网上的证明( ...
- bzoj千题计划231:bzoj1997: [Hnoi2010]Planar
http://www.lydsy.com/JudgeOnline/problem.php?id=1997 如果两条边在环内相交,那么一定也在环外相交 所以环内相交的两条边,必须一条在环内,一条在环外 ...
- BZOJ1997 [Hnoi2010]Planar (2-sat)
题意:给你一个哈密顿图,判断是不是平面图 思路:先找出哈密顿图来.哈密顿回路可以看成一个环,把边集划分成两个集合,一个在环内,一个在外.如果有两条相交边在环内,则一定不是平面图,所以默认两条相交边,转 ...
- BZOJ1997 [Hnoi2010]Planar 【2-sat】
题目链接 BZOJ1997 题解 显然相交的两条边不能同时在圆的一侧,\(2-sat\)判一下就好了 但这样边数是\(O(m^2)\)的,无法通过此题 但是\(n\)很小,平面图 边数上界为\(3n ...
- bzoj1997: [Hnoi2010]Planar
2-SAT. 首先有平面图定理 m<=3*n-6,如果不满足这条件肯定不是平面图,直接退出. 然后构成哈密顿回路的边直接忽略. 把哈密顿回路当成一个圆, 如果俩条边交叉(用心去感受),只能一条边 ...
- bzoj1997 [Hnoi2010]Planar——2-SAT
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1997 神奇的经典2-SAT问题! 对于两个相交的区间,只能一里一外连边,所以可以进行2-SA ...
- bzoj1997 [HNOI2010]平面图判定Plana
bzoj1997 [HNOI2010]平面图判定Planar 链接 bzoj luogu 思路 好像有很多种方法过去.我只说2-sat 环上的边,要不在里面,要不在外边. 有的边是不能同时在里面的,可 ...
- 【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 ...
- BZOJ 1997: [Hnoi2010]Planar( 2sat )
平面图中E ≤ V*2-6.. 一个圈上2个点的边可以是在外或者内, 经典的2sat问题.. ----------------------------------------------------- ...
随机推荐
- githup常用备份
https://github.com/ https://github.com/doumeki/ThrExcel https://github.com/xinxi1990/MyMonkey https: ...
- 如何解决android 通知栏不显示的问题
android 8.0 以后的版本,在创建通知栏的时候,加了一个channelId的东西.要想在上述版本中显示通知,总共分两步 1.创建Channel if (Build.VERSION.SDK_IN ...
- CSP-S 2019文澜中学游记(11.15~11.17)
前言 今年的\(CSP-S\),本以为自己的实力与去年的\(NOIP\)相比,能有较大的提升的. 没想到,菜是原罪,弱就是弱,依然逃脱不了被吊锤的命运. \(Nov\ 15th\):\(Day\ 0\ ...
- 关闭Chrome浏览器的广告
生活没有绝对的对与错:代码就不一样了,错了就编译不过,也正是因为这样,编程的人思维有时也会陷入一种狭隘中,这就是把工作和生活没有分开.Win10 右下角的广告就像程序调试中的"警告" ...
- 【微信小程序】mpvue中页面之间传值(全网唯一真正可行的方法,中指推了一下隐形眼镜)
摘要: mpvue中页面之间传值(注意:是页面之间,不是组件之间) 场景:A页面跳转B页面,在B页面选择商品,将商品名带回A页面并显示 使用api: getCurrentPages step1: A页 ...
- postgresql 笔记
客户端GUI 在官网下载一个,在安装的时候,不安装 server 端,会在客户端 安装一个 pgadmin .
- 《细说PHP》第四版 样章 第二章 PHP的应用与发展 1
<细说PHP>第四版 样章 第二章 PHP的应用与发展 1 学习任何编程语言之前,先了解一下它的应用与发展是很有必要的.从Web开发的历史看来,PHP.Python和Ruby几乎是同时出现 ...
- Spring提供JdbcTemplate&NamedParameterJdbcTemplate
JdbcTemplate主要提供以下五类方法: execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句: update方法及batchUpdate方法:update方法用于执行新增.修 ...
- java 接口中的成员变量与方法
java接口中变量的默认修饰符为 public static final int i = 3; 相当于 public static final int i = 3; java接口中方法的默认修饰符为 ...
- centos7下mysql5.7的安装与配置
centos7下MySQL5.7的安装与配置 下载 下载地址 根据系统和版本选择红框中的四个RPM包下载即可,然后放到centos7系统中的/opt目录下,等待稍后安装. 安装前的准备 1. 检查系统 ...