平面图

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

平面图定理

边数大于点数的三倍减六的图一定不是平面图。即设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. 面试官:给我讲讲SpringBoot的依赖管理和自动配置?

    1.前言 从Spring转到SpringBoot的xdm应该都有这个感受,以前整合Spring + MyBatis + SpringMVC我们需要写一大堆的配置文件,堪称配置文件地狱,我们还要在pom ...

  2. 我试了试用 SQL查 Linux日志,好用到飞起

    大家好,我是小富~ 最近发现点好玩的工具,迫不及待的想跟大家分享一下. 大家平时都怎么查Linux日志呢? 像我平时会用tail.head.cat.sed.more.less这些经典系统命令,或者aw ...

  3. java并发编程实战之线程安全性(一)

    1.1什么是线程安全性 要对线程安全性给出一个确切的定义是非常复杂的.最核心的概念就是正确性.正确性:某个类的行为与其规范完全一致.在良好的规范中通常会定义各种不变性条件来约束对象的状态,以及定义各种 ...

  4. 【题解】Luogu p2986 [USACO10MAR]伟大的奶牛聚集Great Cow Gat 树型dp

    题目描述 Bessie is planning the annual Great Cow Gathering for cows all across the country and, of cours ...

  5. Unity异步加载进度条

    先上代码: using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngi ...

  6. 15 自动发布Java项目(Tomcat)

    #!/bin/bash export PAHT=/usr/local/maven/bin:/usr/local/jdk/bin:/usr/local/sbin:/usr/local/bin:/usr/ ...

  7. 解决CentOS下service 功能 不能使用 bash: service: command not found

    首先检查自己是否 使用的是root用户 在centos系统中,如果/sbin目录下没有service这个命令,就会出现 bash: service: command not found 解决步骤如下: ...

  8. 1、如何通过xstart远程连接桌面

    1.1.安装依赖包: 1.安装语言包: [root@slave-node2 ~]# yum groupinstall -y "Fonts" [root@slave-node2 ~] ...

  9. 11、gitlab和Jenkins整合(2)

    5.补充: (1)构建说明: 1)Jenkins会基于一些处理器任务后,构建发布一个稳健指数 (从0-100 ),这些任务一般以插件的方式实现. 2)它们可能包括单元测试(JUnit).覆盖率(Cob ...

  10. 21、oracle打开和关闭归档日志的方法

    21.1.介绍: 在实际应用中,我们需要实现对数据的备份,其实现方式主要有冷备份和热备份两种,现在我们主要讨论热备份的具体操作. 热备份也称为联机备份,在数据库的存档模式下进行备份,oracel数据库 ...