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

  • 相关阅读:
    MVC3、如何应用EntityFramework 连接MySql 数据库 Kevin
    DEV EXPRESS Summary Footer 不显示 Kevin
    装饰模式 Kevin
    Dev 控件 GridControl 控件 二次绑定数据源的问题。 Kevin
    System.InvalidOperationException 异常 Kevin
    LINQ to XML Kevin
    代理模式——代码版“吊丝的故事” Kevin
    VS2012 中的设备 面板 Kevin
    maven 学习笔记(三)创建一个较复杂的 eclipse+android+maven 工程
    maven 学习笔记(一)eclipse+android+maven
  • 原文地址:https://www.cnblogs.com/rvalue/p/7667195.html
Copyright © 2011-2022 走看看