zoukankan      html  css  js  c++  java
  • [BZOJ 1997][Hnoi2010]Planar

    1997: [Hnoi2010]Planar

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 2167  Solved: 804
    [Submit][Status][Discuss]

    Description

    Input

    Output

    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

    HINT

     

    Source

    题解

    思路非常清奇...

    首先图里存在哈密顿回路而且输入中已经给出, 那么如果要判断这个图是否是平面图, 我们首先一定会把这个哈密顿回路画在上面, 而且这部分没有优化余地.

    然后剩下的不在环上的边则有两种选择: 从环里穿过去或者从环外绕过去. 根据边所连接的两个节点在哈密顿回路中的顺序确定如果边同时在环内是否会相交, 如果会相交的话这两条边必须分居哈密顿环两侧. 处理出所有之后判断可行性就好了

    所以这个充满 $NPC$ 问题的题面实际上是个 $2-SAT$ ...QAQ

    然后就是 $2-SAT$ 要加反向边(NOI 2017的惨痛教训)

    参考代码

    GitHub

      1 #include <stack>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cstdlib>
      5 #include <iostream>
      6 #include <algorithm>
      7 
      8 const int MAXEX=1e6+10;
      9 const int MAXE=1e4+10;
     10 const int MAXV=2e3+10;
     11 
     12 struct Edge{
     13     int from;
     14     int to;
     15     Edge* next;
     16 };
     17 Edge E[MAXE];
     18 Edge Ex[MAXEX];
     19 Edge* head[MAXV];
     20 Edge* top=E;
     21 
     22 int v;
     23 int e;
     24 int clk;
     25 int scc;
     26 int dfn[MAXV];
     27 int low[MAXV];
     28 int pos[MAXV];
     29 int cycle[MAXV];
     30 int belong[MAXV];
     31 
     32 bool inStack[MAXV];
     33 
     34 std::stack<int> s;
     35 
     36 void Tarjan(int);
     37 void Initialize();
     38 void Insert(int,int);
     39 
     40 int main(){
     41     int T;
     42     scanf("%d",&T);
     43     while(T--){
     44         Initialize();
     45         if(e>3*v-6){
     46             puts("NO");
     47             continue;
     48         }
     49         int cnt=0;
     50         for(int i=0;i<e;i++){
     51             E[i].from=pos[E[i].from];
     52             E[i].to=pos[E[i].to];
     53             if(E[i].from>E[i].to)
     54                 std::swap(E[i].from,E[i].to);
     55             if(E[i].to-E[i].from==1||E[i].from==1&&E[i].to==v)
     56                 continue;
     57             else
     58                 E[cnt++]=E[i];
     59         }
     60         for(int i=0;i<cnt;i++){
     61             for(int j=i+1;j<cnt;j++){
     62                 if((E[i].from<E[j].from&&E[i].to<E[j].to&&E[i].to>E[j].from)||(E[i].from>E[j].from&&E[i].to>E[j].to&&E[i].from<E[j].to)){
     63                     Insert(2*i+1,2*j);
     64                     Insert(2*i,2*j+1);
     65                     Insert(2*j+1,2*i);
     66                     Insert(2*j,2*i+1);
     67                 }
     68             }
     69         }
     70         for(int i=0;i<2*cnt;i++){
     71             if(dfn[i]==0)
     72                 Tarjan(i);
     73         }
     74         bool ans=true;
     75         for(int i=0;i<cnt;i++){
     76             if(belong[2*i]==belong[2*i+1]){
     77                 ans=false;
     78                 break;
     79             }
     80         }
     81         if(ans)
     82             puts("YES");
     83         else
     84             puts("NO");
     85     }
     86     return 0;
     87 }
     88 
     89 inline void Insert(int from,int to){
     90     top->from=from;
     91     top->to=to;
     92     top->next=head[from];
     93     head[from]=top++;
     94 }
     95 
     96 void Tarjan(int root){
     97     dfn[root]=low[root]=++clk;
     98     inStack[root]=true;
     99     s.push(root);
    100     for(Edge* i=head[root];i!=NULL;i=i->next){
    101         if(dfn[i->to]==0){
    102             Tarjan(i->to);
    103             low[root]=std::min(low[root],low[i->to]);
    104         }
    105         else if(inStack[i->to])
    106             low[root]=std::min(low[root],dfn[i->to]);
    107     }
    108     if(low[root]==dfn[root]){
    109         scc++;
    110         int top;
    111         do{
    112             top=s.top();
    113             belong[top]=scc;
    114             inStack[top]=false;
    115             s.pop();
    116         }while(top!=root);
    117     }
    118 }
    119 
    120 inline void Initialize(){
    121     memset(head,0,sizeof(head));
    122     memset(low,0,sizeof(low));
    123     memset(dfn,0,sizeof(dfn));
    124     clk=scc=0;
    125     top=Ex;
    126     scanf("%d%d",&v,&e);
    127     for(int i=0;i<e;i++){
    128         scanf("%d%d",&E[i].from,&E[i].to);
    129     }
    130     for(int i=1;i<=v;i++){
    131         scanf("%d",cycle+i);
    132         pos[cycle[i]]=i;
    133     }
    134 }
    Backup

  • 相关阅读:
    Pythoy 数据类型序列化——json&pickle 模块
    Python xml 模块
    Spring MVC <mvc:annotation-driven/>的作用
    Spring MVC学习笔记
    springboot配置logback日志
    Git master合并分支时提示“Already up-to-date”
    解决idea tomcat乱码问题
    MYSQL 八大优化方案
    SpringBoot项目集成PageHelper使用
    Git--远程仓库版本回退方法
  • 原文地址:https://www.cnblogs.com/rvalue/p/7667195.html
Copyright © 2011-2022 走看看