zoukankan      html  css  js  c++  java
  • BZOJ1997 [Hnoi2010]Planar (2-sat)

    题意:给你一个哈密顿图,判断是不是平面图

    思路:先找出哈密顿图来。哈密顿回路可以看成一个环,把边集划分成两个集合,一个在环内,一个在外。如果有两条相交边在环内,则一定不是平面图,所以默认两条相交边,转化成2——sat,两条边不能同时在内或外,注意双向加边。(以边来转化成两倍)

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #include<queue>
      5 #include<stack>
      6 #include<bits/stdc++.h>
      7 using namespace std;
      8 #define LL long long
      9 #define clc(a,b) memset(a,b,sizeof(a))
     10 const int maxn = 2000 + 10;
     11 int r(){
     12     int x=0,f=1;char ch=getchar();
     13     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     14     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     15     return x*f;
     16 }
     17 int T,n,m,ind,top,cnt,scc;
     18 int u[10005],v[10005];
     19 int c[2010],pos[2005];
     20 int last[2005],dfn[2005],low[2005],q[2005],bl[2005];
     21 bool inq[2005];
     22 
     23 struct edge{
     24     int to,next;
     25 }e[1000005];
     26 
     27 void add(int u,int v){
     28     e[++cnt].to=v;
     29     e[cnt].next=last[u];
     30     last[u]=cnt;
     31 }
     32 
     33 void tarjan(int x){
     34     inq[x]=1;q[++top]=x;
     35     low[x]=dfn[x]=++ind;
     36     for(int i=last[x];i;i=e[i].next)
     37         if(!dfn[e[i].to])
     38             tarjan(e[i].to),low[x]=min(low[x],low[e[i].to]);
     39         else if(inq[e[i].to])
     40             low[x]=min(low[x],dfn[e[i].to]);
     41     int now=-1;
     42     if(low[x]==dfn[x])
     43     {
     44         scc++;
     45         while(now!=x)
     46         {
     47             now=q[top--];inq[now]=0;
     48             bl[now]=scc;
     49         }
     50     }
     51 }
     52 
     53 bool jude(){
     54     for(int i=1;i<=m;i++){
     55         if(bl[i*2]==bl[i*2-1])
     56             return false;
     57     }
     58  return true;
     59 }
     60 int main(){
     61     T=r();
     62     while(T--){
     63           n=r(),m=r();
     64           for(int i=1;i<=m;i++){
     65             u[i]=r();v[i]=r();
     66           }
     67           clc(last,0);
     68           cnt=0;
     69           scc=ind=0;
     70           clc(low,0);
     71           clc(dfn,0);
     72           for(int i=1;i<=n;i++)
     73             c[i]=r();
     74         if(m>3*n-6){
     75             printf("NO
    ");
     76             continue;
     77         }
     78         for(int i=1;i<=n;i++)
     79             pos[c[i]]=i;
     80         top=0;
     81         for(int i=1;i<=m;i++){
     82             u[i]=pos[u[i]],v[i]=pos[v[i]];
     83             if(u[i]>v[i]) swap(u[i],v[i]);
     84             if(v[i]-u[i]==1||v[i]-u[i]==n-1) continue;
     85             u[++top]=u[i],v[top]=v[i];
     86         }
     87         m=top;
     88         for(int i=1;i<=m;i++){
     89             for(int j=i+1;j<=m;j++){
     90                 if((u[i]<u[j]&&v[i]>u[j]&&v[i]<v[j])||(u[i]>u[j]&&v[j]>u[i]&&v[i]>v[j])){
     91                     add(2*i-1,2*j);
     92                     add(2*i,2*j-1);
     93                     add(2*j-1,2*i);
     94                     add(2*j,2*i-1);
     95                 }
     96             }
     97         }
     98         for(int i=1;i<=2*m;i++){
     99            if(dfn[i]==0){
    100             tarjan(i);
    101            }
    102         }
    103         if(jude()) printf("YES
    ");
    104         else printf("NO
    ");
    105 
    106     }
    107     return 0;
    108 }
    View Code
  • 相关阅读:
    效能分析
    四人小组项目--连连看的设计与实现
    每周工作量及进度统计(第三周)
    四则运算改进版
    词频统计改进版1
    SCRUM站立会议
    四则运算
    效能分析
    四人小组项目的需求和功能等描述
    通读构建之法
  • 原文地址:https://www.cnblogs.com/ITUPC/p/5385206.html
Copyright © 2011-2022 走看看