平面图

平面图就是所有点的连边不相交的图。(当然是在你尽量想让它不相交的情况下)。这一点可以大概理解成拓扑图的性质,即每连一条边就会将某个区域进行分割——很明显,如果两个点分别处在两个不可达的区域,它们要连边显然是要穿过其他边的。

平面图定理

边数大于点数的三倍减六的图一定不是平面图。即设n为点数,m为边数,有

\[m<=n*3-6
\]

关于平面图的其他定理和上定理的证明我不会不过我有大佬博客就不乱搬了。

关于此题题解

首先,它给出了n和m,我们先通过平面图定理判断一下,这样可以偷很多的懒。

然后,我们发现这个题是给了哈密顿回路的。那么我们就可以把这个图伸展成一个环便于理解。

然后,我们发现了这个图的性质——哈密顿回路相当于分割整个平面成了两个区域。也就是说,两个非哈密顿回路上的边的边顶多能共存两组。(因为不能交叉)

两个区域?共存两组?

2-SAT浮现出水面。对,我们可以给非哈密顿回路边的边连边,然后求它们的最大匹配。

(如果没有哈密顿回路这玩意还是个DPC问题)

2-SAT的模板我就不注释了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int read()
{
int x=0,w=0;char c=getchar();
while(!isdigit(c))w|=c=='-',c=getchar();
while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
return w?-x:x;
} namespace star
{
const int maxn=3e4+5,maxv=205,maxm=2e6+5;
int cnt,Cir[maxv],rec[maxn],x1[maxn],y1[maxn],x2[maxn],y2[maxn];
//Cir用来按编号从小到大记录环,rec反向记录Cir;
//x1,y1,x2,y2分别记录全部边和去除环上边的剩余边
int tot,dfn[maxn],low[maxn],_n;
//tarjan用
int ecnt,head[maxm],nxt[maxm],to[maxm],belong[maxn];
//前向星用
bool cir[maxv][maxv];
//cir记录Cir
inline void addedge(int from,int too)
{
to[++ecnt]=too,nxt[ecnt]=head[from],head[from]=ecnt;
} int st[maxn],top;
bool vis[maxn];
void tarjan(int x)
{
dfn[x]=low[x]=++tot;
st[++top]=x;vis[x]=1;
for(int i=head[x];i;i=nxt[i])
{
int u=to[i];
if(!dfn[u]){
tarjan(u);
low[x]=min(low[x],low[u]);
}else if(vis[x]){
low[x]=min(low[x],dfn[u]);
}
} if (dfn[x] == low[x]) {
int v; belong[x] = ++_n;vis[x]=0;
while (v = st[top--], v != x) belong[v] = _n,vis[v]=0;
}
} inline bool check()
{
for(int i=1;i<=(cnt<<1);i++)
if(!dfn[i])tarjan(i);
for(int i=1;i<=cnt;i++)
if(belong[i]==belong[i+cnt])return false;
return true;
} inline void work()
{
int T,n,m;
n=read(),m=read(); memset(head,0,sizeof head);
memset(x1,0,sizeof x1);
memset(y1,0,sizeof y1);
memset(x2,0,sizeof x2);
memset(y2,0,sizeof y2);
memset(belong,0,sizeof belong);
memset(rec,0,sizeof rec);
memset(cir,0,sizeof cir);
memset(dfn,0,sizeof dfn);
memset(low,0,sizeof low);
memset(to,0,sizeof to);
memset(nxt,0,sizeof nxt);
memset(vis,0,sizeof vis);
memset(st,0,sizeof st);
ecnt=tot=cnt=_n=top=0;
for(int i=1;i<=m;i++)
{
x1[i]=read(),y1[i]=read();
if(x1[i]>y1[i]) swap(x1[i],y1[i]);
}//记录下来等会处理 rec[Cir[1]=read()]=1;
for(int i=2;i<=n;i++){
rec[Cir[i]=read()]=i;
(Cir[i]>Cir[i-1]?cir[Cir[i-1]][Cir[i]]:cir[Cir[i]][Cir[i-1]])=1;
}
(Cir[1]>Cir[n]?cir[Cir[n]][Cir[1]]:cir[Cir[1]][Cir[n]])=1;
//获取cir和rec if(m>3*n-6){
printf("NO\n");return;
} for(int i=1;i<=m;i++)
{
if(cir[x1[i]][y1[i]])continue;
x2[++cnt]=x1[i],y2[cnt]=y1[i];
} for(int i=1;i<cnt;i++)
for(int j=i+1;j<=cnt;j++)
{
int a=rec[x2[i]] , b=rec[y2[i]] , x=rec[x2[j]] , y=rec[y2[j]];
if(a>b)swap(a,b);if(x>y)swap(x,y);
if((a<x and b>x and y>b) or (x<a and y>a and b>y))
addedge(i,j+cnt),addedge(j,i+cnt),addedge(i+cnt,j),addedge(j+cnt,i);
}
if(check())printf("YES\n");
else printf("NO\n");
}
} int main()
{
int T=read();
while(T--) star::work();
return 0;
}

P3209-平面图判定的更多相关文章

  1. 洛谷P3209平面图判定 [HNOI2010] 2-sat

    正解:2-sat(并茶几/强连通分量 解题报告: 传送门w 难受死了,连WA5次,正确率又-=INF了QAQ 然后先说下这题怎么做再来吐槽自己QAQ 首先这题其实和NOIp2010的关押罪犯挺像的,然 ...

  2. P3209 [HNOI2010]平面图判定

    P3209 [HNOI2010]平面图判定 哈密尔顿环之外的任意一条边,要么连在环内部,要么连在环外部 判断两条边在同一部分会相交,则这两条边必须分开 那么把边看作点连边,跑二分图染色就行 #incl ...

  3. Luogu P3209 [HNOI2010]平面图判定(2-SAT)

    P3209 [HNOI2010]平面图判定 题意 题目描述 若能将无向图\(G=(V,E)\)画在平面上使得任意两条无重合顶点的边不相交,则称\(G\)是平面图.判定一个图是否为平面图的问题是图论中的 ...

  4. [BZOJ1997][HNOI2010] 平面图判定

    Description Input Output     是的..BZOJ样例都没给.     题解(from 出题人): 如果只考虑简单的平面图判定,这个问题是非常不好做的. 但是题目中有一个条件— ...

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

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

  6. 洛谷 P3209 [HNOI2010] 平面图判定

    链接: P3209 题意: 给出 \(T\) 张无向图 \((T\leq100)\),并给出它对应的哈密顿回路,判断每张图是否是平面图. 分析: 平面图判定问题貌似是有线性做法的,这里给出链接,不是本 ...

  7. 洛谷P3209 [HNOI2010]平面图判定(2-SAT)

    传送门 看到哈密顿回路就被吓傻了……结果没有好好考虑性质…… 首先,平面图有个性质:边数小于等于$3n-6$(我也不知道为啥),边数大于这个的直接pass 然后考虑原图,先把哈密顿回路单独摘出来,就是 ...

  8. [HNOI2010]平面图判定

    Description: 若能将无向图 \(G=(V, E)\) 画在平面上使得任意两条无重合顶点的边不相交,则称 \(G\) 是平面图.判定一个图是否为平面图的问题是图论中的一个重要问题.现在假设你 ...

  9. Luogu3209 HNOI2010 平面图判定 平面图、并查集

    传送门 题意:$T$组数据,每组数据给出一个$N$个点,$M$条边,并存在一个$N$元环的图,试判断其是否为一个可平面图(如果存在一种画法,使得该图与给出的图同构且边除了在顶点处以外互相不相交,则称其 ...

  10. [HNOI2010] 平面图判定 planar

    标签:二分图判定.题解: 首先可以把题目中给你的那个环给画出来,这样就可以发现对于任意一个图来说,如果两条边要相交,就不能让他们相交,那么这两条边就要一条在里面一条在外面,如果把环画成一条链,那么就是 ...

随机推荐

  1. JAVA并发(7)-并发队列PriorityBlockingQueue的源码分析

    本文讲PriorityBlockingQueue(优先阻塞队列) 1. 介绍 一个无界的具有优先级的阻塞队列,使用跟PriorityQueue相同的顺序规则,默认顺序是自然顺序(从小到大).若传入的对 ...

  2. springMVC源码解读笔记

    1: DispatcherServlet 的初始化流程(调用的init方法) a) 初始化spring高级容器,WebApplicationContext(容器初始化12个步骤) Servlet类的i ...

  3. java后端知识点梳理——java集合

    集合概览 Java中的集合,从上层接口上看分为了两类,Map和Collection.Map是和Collection并列的集合上层接口,没有继承关系. Java中的常见集合可以概括如下. Map接口和C ...

  4. 如何避免Nginx将url decode

    灵感来自:https://my.oschina.net/jastme/blog/528541 这是最近玩微服务架构遇到的一个情况,因为Spring Boot 1.5的网关不支持websocket的转发 ...

  5. ElGamal算法

    简介 ElGamal算法可以用于加密和签名,其安全性依赖于计算有限域上离散对数的难度. ElGamal密钥 生成密钥对时,首先选择素数p,两个随机数g和x,g和x都小于p,然后计算: y = g ^ ...

  6. ES6中的Map

    今天小编和大家一起探讨一下引用类型中的map,在其中会有一些map与数组联合应用,还有和map类似的weakmap类型的说明,这篇文章同时也增加了一些操作数组的办法和实际应用.大家也可以关注我的微信公 ...

  7. noip模拟6[辣鸡·模板·大佬·宝藏]

    这怕不是学长出的题吧 这题就很迷 这第一题吧,正解竟然是O(n2)的,我这是快气死了,考场上一直觉得aaaaa n2过不了过不了, 我就去枚举边了,然后调了两个小时,愣是没调出来,然后交了个暴力,就走 ...

  8. Mac为docker和kubectl添加自动命令补全

    我最新最全的文章都在南瓜慢说 www.pkslow.com,欢迎大家来喝茶! 1 前言 自动命令补全是非常有用的功能,特别是当命令有特别多参数时.显然,docker/kubectl就是这样的命令.我们 ...

  9. Kubernetes在生产环境中的一些讨论

    pod是所有一切资源的中心,毫无疑问是Kubernetes中最重要的资源.毕竟, 每个应用都运行在pod中.为了确保知道如何开发能充分利用应用所在环境资源的应用,最后再从应用的角度来仔细看一下pod. ...

  10. Linux系统安装-C7

    1.安装部署操作系统 (1)创建虚拟机,加载系统镜像 (2)进入系统引导界面进行配置 补充:centos7系统网卡名称 默认系统的网卡名称为 eth0 eth1 –centos6 默认系统的网卡名称为 ...