zoukankan      html  css  js  c++  java
  • POJ2723 Get Luffy Out

    2-sat,我们想对于一对钥匙关系应该是a&b=0即不能同时选

    对于一扇门而言应该为a|b=1即要至少选一个

    建图二分即可

    By:大奕哥

      1 #include<iostream>
      2 #include<cstdlib>
      3 #include<cstdio>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<vector>
      7 #include<queue>
      8 using namespace std;
      9 const int N=1e4+10,M=1e7+8;
     10 int ecnt,n,m,nn,top,num,cnt;
     11 int head[N],low[N],dfn[N],col[N],vis[N],s[N];
     12 struct node
     13 {
     14     int a,b;
     15 }key[N],door[N];
     16 struct edge
     17 {
     18     int to,nex;
     19 }e[M];
     20 vector<int>E[N];
     21 void add(int x,int y)
     22 {
     23     e[++ecnt].to=y;e[ecnt].nex=head[x];head[x]=ecnt;
     24 }
     25 void init()
     26 {
     27     ecnt=cnt=num=top=0;
     28     memset(head,0,sizeof(head));
     29     memset(low,0,sizeof(low));
     30     memset(dfn,0,sizeof(dfn));
     31     memset(vis,0,sizeof(vis));
     32     memset(col,0,sizeof(col));
     33     memset(s,-1,sizeof(s));
     34 }
     35 void dfs(int x)
     36 {
     37     vis[x]=1;s[++top]=x;
     38     low[x]=dfn[x]=++cnt;
     39     for(int i=head[x];i;i=e[i].nex)
     40     {
     41         int y=e[i].to;
     42         if(!dfn[y])
     43         {
     44             dfs(y);
     45             low[x]=min(low[x],low[y]);
     46         }
     47         else if(vis[y])
     48         {
     49             low[x]=min(low[x],dfn[y]);
     50         }
     51     }
     52     if(low[x]==dfn[x])
     53     {
     54         num++;
     55         while(s[top+1]!=x)
     56         {
     57             int a=s[top--];
     58             vis[a]=0;
     59             col[a]=num;
     60         }
     61     }
     62     return;
     63 }
     64 bool two_Sat(int mid)
     65 {
     66     init();
     67     for(int i=0;i<n;++i)
     68     {
     69         add(key[i].a+nn,key[i].b);//1&1=1
     70         add(key[i].b+nn,key[i].a);    
     71     }
     72     for(int i=0;i<mid;++i)
     73     {
     74         add(door[i].a,door[i].b+nn);//0|0=0
     75         add(door[i].b,door[i].a+nn);
     76     }
     77     for(int i=0;i<nn*2;++i)
     78     if(!dfn[i])dfs(i);
     79     for(int i=0;i<nn;++i)
     80     {
     81         if(col[i]==col[i+nn])return 0;
     82     }
     83     return 1;
     84 }
     85 int solve()
     86 {
     87     int l=0,r=m,ans=0;
     88     while(l<=r)
     89     {
     90         int mid=l+r>>1;
     91         if(two_Sat(mid))ans=mid,l=mid+1;
     92         else r=mid-1;
     93     }
     94     return ans;
     95 }
     96 int main()
     97 {
     98     while(~scanf("%d%d",&n,&m))
     99     {
    100         if(!n&&!m)break;
    101         nn=n*2;
    102         for(int i=0;i<n;++i)scanf("%d%d",&key[i].a,&key[i].b);
    103         for(int i=0;i<m;++i)scanf("%d%d",&door[i].a,&door[i].b);
    104         printf("%d
    ",solve());
    105     }
    106     return 0;
    107 }
  • 相关阅读:
    fortran imsl 程序库
    使用NET USE将USB端口模拟为LPT1
    Processing鼠标响应(1)
    MATLAB矩阵运算(1)
    Processing中类的定义
    Perl的第二纪
    Processing鼠标响应(2)
    Processing中的图片互动
    gFortran的使用
    用回溯法来产生由0或1组成的2m个二进位串,使该串满足以下要求
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8310723.html
Copyright © 2011-2022 走看看