[bzoj1997][Hnoi2010]Planar(2-sat||括号序列)
开始填连通分量的大坑了= =
然后平面图有个性质m<=3*n-6.....
由平面图的欧拉定理n-m+r=2(r为平面图的面的个数),在极大平面图的情况可以代入得到m=3*n-6。
网上的证明(雾?):
http://blog.chinaunix.net/uid-26510579-id-3183558.html
http://www.zybang.com/question/673815bbe56e8b5639f95234b515b8c5.html
这题把哈密顿回路看成圆,就变成圆上的点之间的边是否能不相交。。和某次模拟赛的T3一模一样= =
显然对于两条会相交的边x,y,x和y既不能同时在圆内,也不能同时在圆外。。。就转换成2-sat问题了。。
若使x表示x在圆内,x'表示x在圆外,因为x,y不能同时在圆内,所以连上(x,y')和(y,x'),然后还不能同时在圆外,就再连(x',y)和(y',x)。
然后就是模板了。。。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=;
const int maxm=;
struct zs{
int too,pre;
}e[maxm];
struct zzs{
int from,too;
}a[maxn*];
int last[maxn**],dfn[maxn**],low[maxn**],st[maxn**],bel[maxn**];
bool ins[maxn**];
int from[maxn*],too[maxn*],id[maxn];
int tot,tim,num,i,j,k,n,m,x,y,top,tt;
inline bool cant(int x,int b){
if(a[x].from>a[b].from)swap(x,b);
if(a[b].from>a[x].from&&a[b].from<a[x].too&&a[b].too>a[x].too)return ;
return ;
}
void insert(int a,int b){
// printf("%d-->%d\n",a,b);
e[++tot].too=b;e[tot].pre=last[a];last[a]=tot;
e[++tot].too=a;e[tot].pre=last[b];last[b]=tot;
}
void tarjan(int x){
dfn[x]=low[x]=++tim;
st[++top]=x;;ins[x]=;
for(int i=last[x];i;i=e[i].pre)if(!dfn[e[i].too]){
tarjan(e[i].too);low[x]=min(low[x],low[e[i].too]);
}else if(ins[e[i].too])low[x]=min(low[x],dfn[e[i].too]);
if(dfn[x]==low[x]){
num++;
while(st[top+]!=x){
ins[st[top]]=;bel[st[top]]=num;
top--;
}
}
}
bool cmp(zzs a,zzs b){
return a.from<b.from||(a.from==b.from&&a.too<b.too);
}
int main(){
scanf("%d",&tt);
while(tt--){
scanf("%d%d",&n,&m);
if(m>n*-){
for(i=;i<=m<<;i++)scanf("%d",&j);
for(i=;i<=n;i++)scanf("%d",&j);
printf("NO\n");continue;
}
top=tim=tot=num=;
memset(dfn,,*(*m+));
memset(last,,*(*m+));
for(i=;i<=m;i++)scanf("%d%d",&a[i].from,&a[i].too); for(i=;i<=n;i++)scanf("%d",&j),id[j]=i;
for(i=;i<=m;i++){
a[i].from=id[a[i].from];a[i].too=id[a[i].too];
if(a[i].from>a[i].too)swap(a[i].from,a[i].too);
}//按哈密顿回路给点重新编号,使1~n依次对应环中的点
sort(a+,a++m,cmp);j=;
for(i=;i<=m;i++){
if(a[i].from+==a[i].too||a[i].too%n+==a[i].from)continue;
j++;
a[j].from=a[i].from,a[j].too=a[i].too;
}
m=j;
for(i=;i<m;i++)for(j=i+;j<=m;j++){
if(cant(i,j))insert(i*,j*-),insert(j*,i*-);//,printf("%d&&&%d\n",i,j);
if(a[j].from>=a[i].too)break;
}
for(i=;i<=*m;i++)if(!dfn[i])tarjan(i);
bool flag=;
for(i=;i<=m;i++)if(bel[i*]==bel[i*-]){flag=;break;
}
if(flag)printf("NO\n");else printf("YES\n");
}
return ;
}
系统:正在比对你的代码和黄学长的代码。。。。
找不到差异QAQ
当然了kpm大爷那场是玩成括号序列。。。。把边的两端点看成是左括号和右括号,那么圆内和圆外分别是一个合法的括号序列。。算括号序列的时候记录一下每条边会与别的哪些边冲突,按冲突关系建图后二分染色就知道是否可能合法了。。。
感觉也可以两个括号序列一起上。。其中一个出现冲突后就把冲突的那些边都扔到另外一个括号序列里面,如果再冲突就是无解了。。当然了我只是嘴巴选手(跑
1997: [Hnoi2010]Planar
Time Limit: 10 Sec Memory Limit: 64 MB
Submit: 1093 Solved: 428
[Submit][Status][Discuss]
Description

Input

Output

Sample Input
Sample Output
HINT
Source
//没有样例差评
[bzoj1997][Hnoi2010]Planar(2-sat||括号序列)的更多相关文章
- bzoj千题计划231:bzoj1997: [Hnoi2010]Planar
http://www.lydsy.com/JudgeOnline/problem.php?id=1997 如果两条边在环内相交,那么一定也在环外相交 所以环内相交的两条边,必须一条在环内,一条在环外 ...
- [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)
题意:给你一个哈密顿图,判断是不是平面图 思路:先找出哈密顿图来.哈密顿回路可以看成一个环,把边集划分成两个集合,一个在环内,一个在外.如果有两条相交边在环内,则一定不是平面图,所以默认两条相交边,转 ...
- 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]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 ...
- bzoj1997 [HNOI2010]平面图判定Plana
bzoj1997 [HNOI2010]平面图判定Planar 链接 bzoj luogu 思路 好像有很多种方法过去.我只说2-sat 环上的边,要不在里面,要不在外边. 有的边是不能同时在里面的,可 ...
- BZOJ4350: 括号序列再战猪猪侠
Description 括号序列与猪猪侠又大战了起来. 众所周知,括号序列是一个只有(和)组成的序列,我们称一个括号 序列S合法,当且仅当: 1.( )是一个合法的括号序列. 2.若A是合法的括号序列 ...
随机推荐
- LINUX:alias命令详解
发现目前安装的g++并没有开启选项 -std=c++11,无法使用c++11的新标准及其中的列表初始化.搜索后得到解决方法:键入:alias g++="g++ -std=c++11&quo ...
- iOS: FFmpeg编译和使用 学习
ffmpeg是一个多平台多媒体处理工具,处理视频和音频的功能非常强大.目前在网上搜到的iOS上使用FFMPEG的资料都比较陈旧,而FFMPEG更新迭代比较快: 且网上的讲解不够详细,对于初次接触FFM ...
- iOS 面试题、知识点 之一
最近面试,发现这些题个人遇到的几率大一些,与大家分享一下,分三文给大家: 当然Xcode新版本与之前一版本的区别,以及iOS新特性是必要了解的吧. Xcode8 和iOS 10 在之前文章有发过,感兴 ...
- 深度搜索DFS-Lake Counting(POJ NO.2386)
题目链接POJ NO.2386 解题思路: 这个也是一个dfs 的应用,在书上的例子,因为书上的代码并不全,基本都是函数分块来写,通过这个题目也规范了代码,以后能用函数的就都用函数来实现吧.采用深度优 ...
- C 函数参数 char **s与char *s[]
本文同时发表在https://github.com/zhangyachen/zhangyachen.github.io/issues/126 先来看一个小例子 : 编写函数遍历一个整型数组的元素,数组 ...
- xamarin android checkbox自定义样式
xamarin android checkbox自定义样式 在drawable文件在新建checkbox_bg.xml文件 <?xml version="1.0" encod ...
- 转载|chrome developer tool—— 断点调试篇
断点,调试器的功能之一,可以让程序中断在需要的地方,从而方便其分析.也可以在一次调试中设置断点,下一次只需让程序自动运行到设置断点位置,便可在上次设置断点的位置中断下来,极大的方便了操作,同时节省了时 ...
- fdisk 命令详解
fdisk 作用: 查看磁盘实体使用情况,也可对硬盘分区. 选项: -b 分区大小 -l 列出指定的外围设备的分区表状况 -s 分区编号, 将指定的分区大小输出到标准输出上, 单位为区块 -u ...
- JMeter IP欺骗压测
要求:JMeter版本2.5以上 IP欺骗其实是LR自带的一个非常有用的功能. 为什么会用到IP欺骗? 1)当某个IP的访问过于频繁,或者访问量过大是,服务器会拒绝访问请求,这时候通过IP欺骗可以增加 ...
- C# Excel数据导入到数据库
http://www.jb51.net/article/44743.htm 假如Excel中的数据如下: 数据库建表如下: 其中Id为自增字段: 代码: 复制代码 代码如下: using System ...