zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    SAP S/4HANA extensibility扩展原理介绍
    SAP CRM系统订单模型的设计与实现
    使用nodejs代码在SAP C4C里创建Individual customer
    SAP Cloud for Customer Account和individual customer的区别
    Let the Balloon Rise map一个数组
    How Many Tables 简单并查集
    Heap Operations 优先队列
    Arpa’s obvious problem and Mehrdad’s terrible solution 思维
    Passing the Message 单调栈两次
    The Suspects 并查集
  • 原文地址:https://www.cnblogs.com/PotremZ/p/BZOJ1997.html
Copyright © 2011-2022 走看看