• BZOJ 1997: [Hnoi2010]Planar 2-SAT


    $ ightarrow $ 戳我进BZOJ原题

    [Hnoi2010]Planar

    Time Limit: 10 Sec Memory Limit: 64 MB
      ### Description

    pic1

     

    Input

    pic2

     

    Output

    pic3

     

    Sample Input

     2 
     6 9 
     1 4 
     1 5 
     1 6 
     2 4 
     2 5 
     2 6 
     3 4 
     3 5 
     3 6 
     1 4 2 5 3 6 
     5 5 
     1 2 
     2 3 
     3 4 
     4 5 
     5 1 
     1 2 3 4 5
    

     

    Sample Output

    NO
    YES
    

     

    Source

    Day1
     

    题目大意

    • 给定一张无向图以及图中的一个哈密顿回路,判断无向图是否为平面图

    • $ n le 200.m le 1000 $
       

    题解

    • 除去哈密顿回路( $ n $ 个点的环)之外,每条边有环内、环外两个赋值

    • 若两条边对应环上的区间有重叠,则不能同时在环内或者环外

    • 产生4个条件“若 $ x $ 则 $ y' $ ” “若 $ x' $ 则 $ y $ ” “ 若 $ y $ 则 $ x' $ ” “ 若 $ y' $ 则 $ x $ ”

    • 按照 $ 2-SAT $ 模型求解即可
       

    代码

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<stack>
    using namespace std;
    #define M 10005
    #define N 2005
     
    struct edge{ int v,nxt; }e[N<<8];
    int head[N],tot;
    void add(int u,int v){
        e[++tot].v=v; e[tot].nxt=head[u]; head[u]=tot;
    }
     
    int n,m,T,u[M],v[M],c[N],pos[N];
    stack<int>s;
    int dfn[N],low[N],bel[N],tim,scc,cnt;
    bool vis[N];
     
    void tarjan(int u){
        dfn[u]=low[u]=++tim; s.push(u); vis[u]=1;
        for(int i=head[u];i;i=e[i].nxt)
            if(!dfn[e[i].v]){
                tarjan(e[i].v);
                low[u]=min(low[u],low[e[i].v]);
            } else if(vis[e[i].v])
                low[u]=min(low[u],dfn[e[i].v]);
        if(dfn[u]==low[u]){
            ++scc; 
            do{
                u=s.top(); s.pop(); vis[u]=0;
                bel[u]=scc;
            }while(dfn[u]!=low[u]); }
    }
    inline bool judge(){
        for(int i=1;i<=cnt;++i)
            if(bel[2*i]==bel[2*i-1]) return 0;
        return 1;
    }
    inline void init(){
        memset(head,0,sizeof(head));
        memset(low,0,sizeof(low));
        memset(dfn,0,sizeof(dfn));
        cnt=tot=tim=scc=0;
    }
    int main(){
        scanf("%d",&T);
        while(T--){
            scanf("%d %d",&n,&m);
            for(int i=1;i<=m;++i) scanf("%d %d",&u[i],&v[i]);
            for(int i=1;i<=n;++i) scanf("%d",&c[i]);
            if(m>3*n-6){ puts("NO"); continue; }
            init();
            for(int i=1;i<=n;++i) pos[c[i]]=i;
            for(int i=1;i<=m;++i){
                v[i]=pos[v[i]]; u[i]=pos[u[i]];
                if(u[i]>v[i]) swap(u[i],v[i]);
                if(v[i]-u[i]==1||(v[i]==n&&u[i]==1)) continue;
                u[++cnt]=u[i]; v[cnt]=v[i]; 
            }
            for(int i=1;i<=cnt;++i)
                for(int j=i+1;j<=cnt;++j)
                    if((u[i]<u[j]&&u[j]<v[i]&&v[i]<v[j])||(u[j]<u[i]&&u[i]<v[j]&&v[j]<v[i])){
                        add(2*i-1,2*j);
                        add(2*i,2*j-1);
                        add(2*j-1,2*i);
                        add(2*j,2*i-1);
                    }
            for(int i=1;i<=2*cnt;++i) if(!dfn[i]) tarjan(i);
            if(judge()) puts("YES");
            else puts("NO");
        }
        return 0;
    }
    
  • 相关阅读:
    网站色彩搭配
    web前端小知识,安书整理的
    java基础
    简单android UI必会
    java学习总结
    java字符常量与字符串常量的区别
    最近的学习
    简单的ps操作
    HTTP协议概述
    ABP 学习 Setting
  • 原文地址:https://www.cnblogs.com/PotremZ/p/BZOJ1997.html
Copyright © 2020-2023  润新知