http://www.lydsy.com/JudgeOnline/problem.php?id=1997

1997: [Hnoi2010]Planar

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 1810  Solved: 684
[Submit][Status][Discuss]

Description

Input

Output

Sample Input

2
6 9
1 4
1 5
1 6
2 4
2 5
2 6
3 4
3 5
3 6
1 4 2 5 3 6
5 5
1 2
2 3
3 4
4 5
5 1
1 2 3 4 5

Sample Output

NO
YES

思路:(from 出题人):http://www.cnblogs.com/jinkun113/p/4894499.html

如果只考虑简单的平面图判定,这个问题是非常不好做的。

但是题目中有一个条件——这张图存在一条哈密顿回路。

我们把哈密顿回路在平面上画成一个圆。仔细观察一下。

每条边如果画在圆内都是一条弦,那如果弦在圆内相交怎么办?把另一条弦翻出去。能不能两条弦都翻出去呢?不能,因为如果两条边在圆内相交,那么它们在圆外也会相交。那我们是不是就相当于就多了一个条件:这两条边不能同时在一个域内。
所以,这张图中总共只有两个域,圆内和圆外。那么我们是不是就转化了模型:有若干个点和若干条边,你要给每个点黑白染色,使得每条边的两个端点颜色不同。直接DFS就可以了。还有个问题,边数是10^4,暴力连边会超时,但是平面图有一个定理:m<=3*n+6,那这个定理来剪枝就行了。
 
 
然后我们只要对输入的哈密顿环进行标号,然后这样就是一个圈,假定刚开始都是在圈内,然后我们只需要判断是否在圈内就行了。

好像我的代码因为用了map和edges这些东西,所以跑的速度比别人慢一个log= =,别人都是200ms左右,我是2000ms,人生第一次体验到了map所带来的绝望

#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker,"/STACK:102400000,102400000")
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define haha printf("haha\n")
const int maxn = 1e5 + ;
struct TwoSat{
int n, c, s[maxn * ];
bool mark[maxn << ];
vector<int> G[maxn << ]; void init(int n){
this->n = n;
for (int i = ; i < * n; i++) G[i].clear();
memset(mark, false, sizeof(mark));
} void add_edge(int x, int xval, int y, int yval){
x = x * + xval, y = y * + yval;
G[x ^ ].pb(y), G[y ^ ].pb(x);
} void display(){
for (int i = ; i < * n; i++){
printf("from = %d\n", i);
for (int j = ; j < G[i].size(); j++){
printf("%d ", G[i][j]);
}
cout << endl;
}
} bool dfs(int x){
if (mark[x ^ ]) return false;
if (mark[x]) return true;
mark[x] = true;
s[c++] = x;
for (int i = ; i < G[x].size(); i++){
if (!dfs(G[x][i])) return false;
}
return true;
} bool solve(){
for (int i = ; i < n * ; i += ){
if (!mark[i] && !mark[i + ]){
c = ;
if (!dfs(i)){
while (c) mark[s[--c]] = false;
if (!dfs(i + )) return false;
}
}
}
return true;
} };
TwoSat tar;
int n, m;
map<int, int> id;
map<pair<int, int>, int> Point;
vector<pair<int, int> > edges; bool test(int u1, int v1, int u2, int v2){
if (u2 > u1 && u2 < v1 && v2 > v1) return true;
if (u1 > u2 && u1 < v2 && v1 > v2) return true;
return false;
} int main(){
int T; cin >> T;
while (T--){
scanf("%d%d", &n, &m);
id.clear();
edges.clear();
for (int i = ; i < m; i++){
int u, v; scanf("%d%d", &u, &v);
if (u > v) swap(u, v);
edges.push_back(mk(u, v));
}
for (int i = ; i <= n; i++){
int u; scanf("%d", &u);
id[u] = i;
}
if (m >= n * + ){
puts("NO"); continue;
}
tar.init(m);
for (int i = ; i < m; i++){
int x1 = edges[i].fi, y1 = edges[i].se;
x1 = id[x1], y1 = id[y1];
if (x1 > y1) swap(x1, y1); for (int j = i + ; j < m; j++){
int x2 = edges[j].fi, y2 = edges[j].se;
x2 = id[x2], y2 = id[y2];
if (x2 > y2) swap(x2, y2);
//if (x1 == x2 || x1 == y2 || y1 == x2 || y1 == y2) continue;
if (test(x1, y1, x2, y2)){///假定刚开始都是在里面的
tar.add_edge(i, , j, );
tar.add_edge(i, , j, );
}
}
}
//tar.display();
if (tar.solve()) puts("YES");
else puts("NO");
}
return ;
}

条件转化,2-sat BZOJ 1997的更多相关文章

  1. HDU 3062 && HDU 1824 && POJ 3678 && BZOJ 1997 2-SAT

    一条边<u,v>表示u选那么v一定被选. #include <iostream> #include <cstring> #include <cstdio> ...

  2. [BZOJ 1997][HNOI2010]Planar(2-SAT)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1997 分析: 考虑每条边是在圈子里面还是圈子外面 所以就变成了2-SAT判定问题了= ...

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

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

  4. bzoj 1997 [Hnoi2010]Planar——2-SAT+平面图的一个定理

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1997 平面图的一个定理:若边数大于(3*点数-6),则该图不是平面图. 然后就可以2-SAT ...

  5. Bzoj 1997 [Hnoi2010]Planar题解

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

  6. bzoj 1997: [Hnoi2010]Planar

    #include<cstdio> #include<cstring> #include<iostream> #define M 20005 #define N 20 ...

  7. 【BZOJ 1997】[Hnoi2010]Planar

    Description Input Output   找到哈密尔顿环之后找到不在哈密尔顿环上的边 这些边如果同时在里面相交那他们同时在外面也相交,所以只能一外一内,这就变成了2-SAT,判一下就好了 ...

  8. bzoj 1997: [Hnoi2010]Planar【瞎搞+黑白染色】

    脑补一下给出的图:一个环,然后有若干连接环点的边,我们就是要求这些边不重叠 考虑一下不重叠的情况,两个有交边一定要一个在环内一个在环外,所以把相交的边连边,然后跑黑白染色看是否能不矛盾即可(可能算个2 ...

  9. 装载:关于拉格朗日乘子法与KKT条件

    作者:@wzyer 拉格朗日乘子法无疑是最优化理论中最重要的一个方法.但是现在网上并没有很好的完整介绍整个方法的文章.我这里尝试详细介绍一下这方面的有关问题,插入自己的一些理解,希望能够对大家有帮助. ...

随机推荐

  1. 网页调用vlc并播放网络视频

    环境:windows/android/ios windows端保存以下内容为reg文件并运行 Windows Registry Editor Version 5.00 [HKEY_CLASSES_RO ...

  2. 单机安装 consul ui 对外提供服务

    Consul 安装启动ui,外网无法访问,应为Consul 默认绑定127.0.0.1 ,所以外网无法访问. 通过设置 -client 参数来设置     consul agent -server - ...

  3. 软件工程个人作业3——集大通APP案例分析

    第一部分:调研, 评测 1.第一次上手体验 主要界面截图: 感受: 1.界面不美观: 2.特色功能展现模块不突出,以上截图为打开APP所看到的界面展示,但是这些功能都不是该APP的特色功能,显得有些累 ...

  4. SQL Server 怎样生成序列号(虚拟数字辅助表)

    </pre><pre name="code" class="sql">--生成一个"序列" 或者说生成一个" ...

  5. libnl3.2.25安装编译

    1,tar zxvf libnl-3.2.25.tar.gz 2,cd libnl-3.2.25 3,./configure --prefix=/usr  --sysconfdir=/etc  --d ...

  6. Vue2.0 render:h => h(App)

    new Vue({ router, store, //components: { App } vue1.0的写法 render: h => h(App) vue2.0的写法 }).$mount( ...

  7. 第131天:移动web页面的排版与布局

    一.总之一句话, 尽量用mm 毫米作为标准单位. 采用新的相对单位 rem 首先设置html的 font-size 为根大小. html{ font-size:1mm; } .titleheight{ ...

  8. ZOJ3084_S-Nim

    题目的意思是这样的,给定你若干堆石子,每次你可以从任一堆取出某些固定数量的石子,每次取完后必须保证没堆石子的数量不为0,谁无法操作了就算fail. 刚刚开始看题目的时候有点也没有思路,甚至连Sg函数也 ...

  9. 【loj6041】「雅礼集训 2017 Day7」事情的相似度 后缀自动机+STL-set+启发式合并+离线+扫描线+树状数组

    题目描述 给你一个长度为 $n$ 的01串,$m$ 次询问,每次询问给出 $l$ .$r$ ,求从 $[l,r]$ 中选出两个不同的前缀的最长公共后缀长度的最大值. $n,m\le 10^5$ 题解 ...

  10. C++解析(5):内联函数分析

    0.目录 1.常量与宏回顾 2.内联函数 3.内联函数深度探析 4.注意事项 5.小结 1.常量与宏回顾 C++中的const常量可以替代宏常数定义,如: const int A = 3; <- ...