平面图

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

平面图定理

边数大于点数的三倍减六的图一定不是平面图。即设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. Django基础之模型层(01)

    内容概要 查询关键字 MySQL select    from    where    group by    having    order by    distinct    limit    r ...

  2. PAT甲级 1093 Count PAT‘s (25 分) 状态机解法

    题目 原题链接 The string APPAPT contains two PAT's as substrings. The first one is formed by the 2nd, the ...

  3. nvm安装管理nodejs

    安装nodejs运行环境 相关连接 步骤 下载nvm-window并安装: https://github.com/coreybutler/nvm-windows/releases 下载完成后直接解压安 ...

  4. golang 模板语法使不解析html标签及特殊字符

    场景 有时候需要使用go的模板语法,比如说用go 去渲染html页面的时候,再比如说用go的模板搞代码生成的时候.这时候可能会遇到一个麻烦,不想转译的特殊字符被转译了. 我遇到的情况是写代码生成器的时 ...

  5. 我是怎么写 Git Commit message 的?

    目录 作用 用的什么规范? type scope subject body footer 参考文章 用的什么辅助工具? 作用 编写格式化的 commit message 能够大大提高代码的维护效率. ...

  6. 一文带你了解.Net信号量

    本文主要讲解.Net基于Semaphore带大家了解信号量 信号量举例 大家去银行去银行取钱,互斥锁管理的时一个柜台是否正在处理业务,而信号量管理的是整个柜台是否正在处理业务,每当有一个柜台处理完成之 ...

  7. 探索颜色渐变绘制算法(基于Processing语言) 第一部分

    突然间意识到连续变化的颜色在程序中是如何实现的这一问题.没错,就想有事找事,我会分好几部分慢慢探寻,其实笔者也不会,咱一起研究.ok,我们开始! 第一部分 初始部分就从官方案例来入手学习.官方给了三个 ...

  8. 7、解决windows10家庭版无法远程连接服务器的问题

    (1)方法一: 升级windows10为专业版,因为win10家庭版没有组策略: (2)方法二:通过远程命令: 同时按住"win+r"键调出"运行",在方框内输 ...

  9. keycloak~账号密码认证和授权码认证

    用户名密码登录 POST /auth/realms/demo/protocol/openid-connect/token 请求体 x-www-form-urlencoded grant_type:pa ...

  10. Destroying The Graph 最小点权集--最小割--最大流

    Destroying The Graph 构图思路: 1.将所有顶点v拆成两个点, v1,v2 2.源点S与v1连边,容量为 W- 3.v2与汇点连边,容量为 W+ 4.对图中原边( a, b ), ...