HNOI2010 平面图判定(planar)
题目链接:戳我
我怎么知道平面图有这个性质??
对于一个平面图,它的边数不超过点数的\(3n-6\)
所以可以直接把边数多的特判掉,剩下的图中边数和点数就是一个数量级的了。
因为这个图存在欧拉回路,所以我们先把那些构成欧拉回路的边拉出来,将边上的两个端点的标号替换成在这个序列上的位置。然后判断这些边能不能不相交。
对于两条边\(i,j\)(分别对应\((u1,v1),(u2,v2)\)),如果\(u1<u2<v1<v2\)——
那么这两个边肯定相交,不是平面图!!
那么这两个边肯定一个在环的内部,一个在外部。这种只有两种状态进行规划,判断有没有合法方案的题——显然能想到2-SAT。
我们连四条边,分别表示:
- i在内部那么j一定在外部
- i在外部那么j一定在内部
- j在内部那么i一定在外部
- j在外部那么i一定在内部
然后tarjan判断一下有没有同一条边的两个状态在一个SCC里即可。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 100010
using namespace std;
int n,m,t,tot,cnt,kkk,top,T;
int a[MAXN],b[MAXN],head[MAXN],pos[MAXN];
int dfn[MAXN],low[MAXN],in[MAXN],st[MAXN],c[MAXN];
struct Edge{int nxt,to,dis;}edge[MAXN<<1];
struct Line{int u,v;}line[MAXN<<1];
inline void add(int from,int to)
{
    // printf("[%d %d]\n",from,to);
    edge[++t].nxt=head[from],edge[t].to=to,head[from]=t;
}
inline void tarjan(int x)
{
    dfn[x]=low[x]=++tot;
    st[++top]=x;
    in[x]=1;
    for(int i=head[x];i;i=edge[i].nxt)
    {
        int v=edge[i].to;
        if(!dfn[v]) tarjan(v),low[x]=min(low[x],low[v]);
        else if(in[v]) low[x]=min(low[x],dfn[v]);
    }
    if(dfn[x]==low[x])
    {
        int v;
        cnt++;
        do{v=st[top--],in[v]=0,c[v]=cnt;}while(x!=v);
    }
}
inline bool check()
{
    for(int i=1;i<=m;i++)
        if(c[i]==c[i+m])
            return false;
    return true;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d",&T);
    while(T--)
    {
        memset(head,0,sizeof(head));
        memset(dfn,0,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(in,0,sizeof(in));
        tot=top=cnt=t=kkk=0;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++) scanf("%d%d",&line[i].u,&line[i].v);
        for(int i=1;i<=n;i++)
        {
            int x;
            scanf("%d",&x);
            pos[x]=i;
        }
        for(int i=1;i<=m;i++) line[i].u=pos[line[i].u],line[i].v=pos[line[i].v];
        if(m>3*n-6)
        {
            printf("NO\n");
            continue;
        }
        for(int i=1;i<=m;i++)
            if(abs(line[i].u-line[i].v)!=1)
            {
                line[++kkk]=line[i];
                if(line[kkk].u>line[kkk].v) swap(line[kkk].u,line[kkk].v);
            }
        m=kkk;
        for(int i=1;i<=m;i++)
            for(int j=1;j<=m;j++)
                if(line[i].u<line[j].u&&line[j].u<line[i].v&&line[j].v>line[i].v)
                    add(i+m,j),add(i,j+m),add(j,i+m),add(j+m,i);
        for(int i=1;i<=2*m;i++)
            if(!dfn[i])
                tarjan(i);
        // for(int i=1;i<=m;i++)
            // printf("%d %d\n",c[i],c[i+m]);
        if(check()==true) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}
HNOI2010 平面图判定(planar)的更多相关文章
- [HNOI2010] 平面图判定 planar
		标签:二分图判定.题解: 首先可以把题目中给你的那个环给画出来,这样就可以发现对于任意一个图来说,如果两条边要相交,就不能让他们相交,那么这两条边就要一条在里面一条在外面,如果把环画成一条链,那么就是 ... 
- BZOJ1997 HNOI2010 平面图判定 planar (并查集判二分图)
		题意 判断一个存在哈密顿回路的图是否是平面图. n≤200,m≤10000n\le200,m\le10000n≤200,m≤10000 题解 如果一定存在一个环,那么连的边要么在环里面要么在外面.那么 ... 
- bzoj1997 [HNOI2010]平面图判定Plana
		bzoj1997 [HNOI2010]平面图判定Planar 链接 bzoj luogu 思路 好像有很多种方法过去.我只说2-sat 环上的边,要不在里面,要不在外边. 有的边是不能同时在里面的,可 ... 
- P3209 [HNOI2010]平面图判定
		P3209 [HNOI2010]平面图判定 哈密尔顿环之外的任意一条边,要么连在环内部,要么连在环外部 判断两条边在同一部分会相交,则这两条边必须分开 那么把边看作点连边,跑二分图染色就行 #incl ... 
- Luogu P3209 [HNOI2010]平面图判定(2-SAT)
		P3209 [HNOI2010]平面图判定 题意 题目描述 若能将无向图\(G=(V,E)\)画在平面上使得任意两条无重合顶点的边不相交,则称\(G\)是平面图.判定一个图是否为平面图的问题是图论中的 ... 
- [BZOJ1997][HNOI2010] 平面图判定
		Description Input Output 是的..BZOJ样例都没给. 题解(from 出题人): 如果只考虑简单的平面图判定,这个问题是非常不好做的. 但是题目中有一个条件— ... 
- [HNOI2010]平面图判定
		Description: 若能将无向图 \(G=(V, E)\) 画在平面上使得任意两条无重合顶点的边不相交,则称 \(G\) 是平面图.判定一个图是否为平面图的问题是图论中的一个重要问题.现在假设你 ... 
- Luogu3209 HNOI2010 平面图判定 平面图、并查集
		传送门 题意:$T$组数据,每组数据给出一个$N$个点,$M$条边,并存在一个$N$元环的图,试判断其是否为一个可平面图(如果存在一种画法,使得该图与给出的图同构且边除了在顶点处以外互相不相交,则称其 ... 
- 洛谷P3209 [HNOI2010]平面图判定(2-SAT)
		传送门 看到哈密顿回路就被吓傻了……结果没有好好考虑性质…… 首先,平面图有个性质:边数小于等于$3n-6$(我也不知道为啥),边数大于这个的直接pass 然后考虑原图,先把哈密顿回路单独摘出来,就是 ... 
随机推荐
- 自然语言处理工具HanLP-N最短路径分词
			本篇给大家分享baiziyu 写的HanLP 中的N-最短路径分词.以为下分享的原文,部分地方有稍作修改,内容仅供大家学习交流! 首先说明在HanLP对外提供的接口中没有使用N-最短路径分词器的,作者 ... 
- Eclipse中导入Maven Web项目并配置其在Tomcat中运行
			今天因为实习的关系需要讲公司已经开发的项目导入进Eclipse,而公司的项目是用Maven来构建的所以,需要将Maven项目导入进Eclipse下. 自己因为没有什么经验所以搞了得两个多小时,在这里和 ... 
- HDU 2041 DP
			URL:https://vjudge.net/problem/HDU-2041 简单DP,因为每次只能走1或者2阶,所以当走到第i阶的时候(i>=4),那么它的前一种状态只可能是i-1和i-2, ... 
- Mac 安装 Homebrew
			为什么要在 MAC 上安装 Homebrew 它干什么用的呢?我们知道在 CentOS 和 Ubuntu 上都有自己的包管理工具,但是在 MAC 上却没有这样类似的管理工具. # CentOS $ y ... 
- cookie,session,token的理解
			Get POST 区别异同点 淘宝token的 理解 过程算法 防止伪造请求 伪造相对难 简单发展史 登录的操作: 哪些人往自己的购物车中放商品, 也就是说我必须把每个人区分开,这就是一个 ... 
- MySQL_入手<二>之删--改--查
			接上 上篇文章继续 查询 # 比较运算 # 根据WHERE条件查找数据: = > < >= <= != select * from t_hero where age < ... 
- 使用Python基于OpenCV和Tesseract的OCR
			OCR OCR(Optical Character Recognition,光学字符识别)是指电子设备(例如扫描仪或数码相机)检查纸上打印的字符,通过检测暗.亮的模式确定其形状,然后用字符识别方法将形 ... 
- JVM 线上故障排查基本操作 (转)
			前言 对于后端程序员,特别是 Java 程序员来讲,排查线上问题是不可避免的.各种 CPU 飚高,内存溢出,频繁 GC 等等,这些都是令人头疼的问题.楼主同样也遇到过这些问题,那么,遇到这些问题该如何 ... 
- Ansible 常用模块详解
			经过前面的介绍,我们已经熟悉了 Ansible 的一些常识性的东西和如何编译安装Ansible,从本章开始我们将全面介绍 Ansible 的各种生产常用模块,这些也是我们使用 Ansible 的过程中 ... 
- Cypher查询在Neo4j中加载具有点数据类型属性的CSV文件
			我有一个CSV文件,标有3列,ID,纬度,经度.我想将CSV文件加载到Neo4j中并创建具有上述属性的节点.Location:属性应该是具有纬度和经度子属性的点数据类型. CSV是: ID,latit ... 
