zoukankan      html  css  js  c++  java
  • bzoj 1997 [Hnoi2010]Planar——2-SAT+平面图的一个定理

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1997

    平面图的一个定理:若边数大于(3*点数-6),则该图不是平面图。

    然后就可以2-SAT了!

    注意把输入读完再用定理continue!!!

    注意边是元素,所以是i+m,而且数组也应开成M<<1!!!

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=405,M=605;
    int T,n,m,hd[M<<1],xnt,x[M],y[M],mp[N];
    int dfn[M<<1],low[M<<1],tim,sta[M<<1],top,col[M<<1],cnt;
    bool ins[M<<1],flag;
    struct Ed{
      int nxt,to;Ed(int n=0,int t=0):nxt(n),to(t) {}
    }ed[(M*M)<<1];
    bool check(int i,int j)
    {
      int x1=mp[x[i]],y1=mp[y[i]],x2=mp[x[j]],y2=mp[y[j]];
      if(x1>y1)swap(x1,y1);
      if((x2>x1&&x2<y1&&(y2>y1||y2<x1))||(y2>x1&&y2<y1&&(x2>y1||x2<x1)))return true;
      return false;
    }
    void add(int i,int j)
    {
      ed[++xnt]=Ed(hd[i],j+m);hd[i]=xnt;
      ed[++xnt]=Ed(hd[j],i+m);hd[j]=xnt;
      ed[++xnt]=Ed(hd[i+m],j);hd[i+m]=xnt;
      ed[++xnt]=Ed(hd[j+m],i);hd[j+m]=xnt;
    }
    void tarjan(int cr)
    {
      dfn[cr]=low[cr]=++tim;
      sta[++top]=cr;ins[cr]=1;
      for(int i=hd[cr],v;i;i=ed[i].nxt)
        if(!dfn[v=ed[i].to])tarjan(v),low[cr]=min(low[cr],low[v]);
        else if(ins[v])low[cr]=min(low[cr],dfn[v]);
      if(dfn[cr]==low[cr])
        {
          cnt++;
          while(sta[top]!=cr)col[sta[top]]=cnt,ins[sta[top--]]=0;
          top--;col[cr]=cnt;ins[cr]=0;
        }
    }
    int main()
    {
      scanf("%d",&T);
      while(T--)
        {
          scanf("%d%d",&n,&m);int z;
          for(int i=1;i<=m;i++)scanf("%d%d",&x[i],&y[i]);
          for(int i=1;i<=n;i++)
        scanf("%d",&z),mp[z]=i;
          if(m>3*n-6){printf("NO
    ");continue;}//先把输入都读完再continue!!! 
          memset(hd,0,sizeof hd);xnt=0;
          for(int i=1;i<m;i++)
        for(int j=i+1;j<=m;j++)
          if(check(i,j))add(i,j);
          memset(dfn,0,sizeof dfn);tim=0;cnt=0;
          for(int i=1;i<=2*m;i++)if(!dfn[i])tarjan(i);
          flag=0;
          for(int i=1;i<=m;i++)
        if(col[i]==col[i+m]){flag=1;break;}
          if(flag)printf("NO
    ");
          else printf("YES
    ");
        }
      return 0;
    }
  • 相关阅读:
    eclipse的下载安装
    找不到符号 类string
    [转]Android_开源框架_AndroidUniversalImageLoader网络图片加载
    [转]移动web开发经验总结
    测试一下吧
    javascript 的 encodeURIComponent 函数用 Objective-C 实现
    几个Objective-C的HTML解析库
    html test
    一段测试代码
    [转]Embed WebView in Fragment
  • 原文地址:https://www.cnblogs.com/Narh/p/9280407.html
Copyright © 2011-2022 走看看