zoukankan      html  css  js  c++  java
  • 【2-SAT(tarjan)】BZOJ1997-[Hnoi2010]Planar

    【题目大意】
    给出一张存在哈密顿回路的无向图,判断是否是平面图。
    【思路】
    首先平面图的一个性质:边数<=点数*3-6
    因为存在哈密顿回路,可以将回路看作是一个圆,考量不再哈密顿回路中的边。如果两天边相交(判断相交可以随意yy一下),那么必然一条在圆内一条在圆外,显然是2-SAT。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<vector>
      6 #include<stack>
      7 using namespace std;
      8 const int MAXN=20000+50;
      9 int n,m;
     10 int u[MAXN],v[MAXN],pos[MAXN];
     11 vector<int> E[MAXN];
     12 int dfn[MAXN],low[MAXN],instack[MAXN],col[MAXN],cnt,colcnt;
     13 stack<int> S;
     14  
     15 int cross(int i,int j)
     16 {
     17     int x1=pos[u[i]],y1=pos[v[i]],x2=pos[u[j]],y2=pos[v[j]]; 
     18     if ((x1<x2 && x2<y1 && y1<y2) || (x2<x1 && x1<y2 && y2<y1)) return 1;else return 0;
     19 }
     20  
     21 void addedge(int u,int v)
     22 {
     23     E[u].push_back(v);
     24     E[v].push_back(u);
     25 }
     26  
     27  
     28 void tarjan(int u)
     29 {
     30     dfn[u]=low[u]=++cnt;
     31     S.push(u);
     32     instack[u]=1;
     33       
     34     for (int i=0;i<E[u].size();i++)
     35     {
     36         int son=E[u][i];
     37         if (!instack[son])
     38         {
     39             tarjan(son);
     40             low[u]=min(low[son],low[u]);
     41         }
     42         else
     43         if (instack[son]==1)
     44             low[u]=min(dfn[son],low[u]);
     45     }
     46       
     47     if (dfn[u]==low[u])
     48     {
     49         colcnt++;
     50         int x;
     51         do
     52         {
     53              x=S.top();
     54              S.pop();
     55              col[x]=colcnt;
     56              instack[x]=2;
     57         }while (x!=u);
     58     }
     59 } 
     60  
     61  
     62 void init()
     63 {
     64     scanf("%d%d",&n,&m);
     65     cnt=0,colcnt=0;
     66     for (int i=0;i<MAXN;i++) vector<int>().swap(E[i]);//注意不要忘记清空 
     67     memset(instack,0,sizeof(instack));
     68     for (int i=1;i<=m;i++)
     69         scanf("%d%d",&u[i],&v[i]);
     70     for (int i=1;i<=n;i++)
     71     {
     72         int x;
     73         scanf("%d",&x);
     74         pos[x]=i;
     75     }
     76 }
     77  
     78 void build()
     79 {
     80     for (int i=1;i<=m;i++)
     81         if (pos[u[i]]>pos[v[i]]) swap(u[i],v[i]);
     82     for (int i=1;i<=m;i++)
     83         for (int j=i+1;j<=m;j++)
     84             if (cross(i,j))
     85             {
     86                 addedge(i,j+m);
     87                 addedge(i+m,j);
     88             }
     89 }
     90  
     91 void solve()
     92 {
     93     for (int i=1;i<=2*m;i++) if (!instack[i]) tarjan(i);
     94     int f=1;
     95     for (int i=1;i<=m;i++)
     96         if (col[i]==col[i+m])
     97         {
     98             f=0;
     99             break;
    100         }
    101     if (f) cout<<"YES"<<endl;
    102         else cout<<"NO"<<endl;
    103 }
    104  
    105 int main()
    106 {
    107     int T;
    108     scanf("%d",&T);
    109     while (T--)
    110     {
    111         init();
    112         if (m<=3*n-6)//平面图定理 
    113         {
    114             build();
    115             solve();
    116         }
    117         else
    118             cout<<"NO"<<endl;
    119     }
    120     return 0;   
    121 } 
  • 相关阅读:
    layer ----- 弹层
    php start
    node.js使用iconv-lite和zlib解决gzip压缩和gbk乱码
    AngularJS中promise的使用
    AngularJS中的$routeProvider
    AngularJS入门教程记录
    AngularJS中的$resource
    Javascript原型易错点记录
    触屏相关事件问题记录
    图片预加载
  • 原文地址:https://www.cnblogs.com/iiyiyi/p/5679709.html
Copyright © 2011-2022 走看看