POJ 2723 - Get Luffy Out 读清题意~简单二分2sat

来源:互联网 发布:共享办公软件 编辑:程序博客网 时间:2024/06/05 02:39

        题意:

                  主人公在一个类似于塔结构的地方..每一层有一个门..门上有两个钥匙孔..只要有其中的一片钥匙就能打开门继续往上走了(一个门可能有两个相同的钥匙孔..也可能好几个门都有相同的钥匙孔..)..而所有的钥匙被分成了N个pair..每个pair中只能拿一把钥匙..现在问主人公最多能进入第几层...

        题解:

                 值得注意的是必须通过了K层才能进入K+1层...这样就形成了一种单调关系...可以用二分来解决了..二分层数..然后2-sat判断...


Program:

#include<iostream>#include<stdio.h>#include<string.h>#include<cmath>#include<queue>#include<stack>#include<set>#include<time.h>#include<map>#include<algorithm>#define ll long long#define eps 1e-5#define oo 10007#define pi acos(-1.0)#define MAXN 5005<<1#define MAXM 5000005<<1using namespace std;  struct node{      int y,next;}line[MAXM];vector<int> T[MAXN];int Lnum,_next[MAXN],key[MAXN][2],hash[MAXN],door[MAXN][2];int dfn[MAXN],low[MAXN],tp[MAXN],tpnum,DfsIndex;bool instack[MAXN];stack<int> mystack;void addline(int x,int y){      line[++Lnum].next=_next[x],_next[x]=Lnum,line[Lnum].y=y;}void tarjan(int x){      instack[x]=true,mystack.push(x);      dfn[x]=low[x]=++DfsIndex;      for (int k=_next[x];k;k=line[k].next)      {             int y=line[k].y;             if (!dfn[y])             {                   tarjan(y);                   low[x]=min(low[x],low[y]);             }else             if (instack[y])                   low[x]=min(low[x],dfn[y]);      }      if (low[x]==dfn[x])      {             tpnum++;             do             {                     x=mystack.top();                     mystack.pop();                     instack[x]=false;                     tp[x]=tpnum;             }while (low[x]!=dfn[x]);      }}bool _2sat(int N,int M){      int i,m,k;      for (i=0;i<(N<<1);i++) T[i].clear();      for (i=1;i<=M;i++)            T[door[i][0]].push_back(door[i][1]),           T[door[i][1]].push_back(door[i][0]);      Lnum=0,memset(_next,0,sizeof(_next));      for (i=0;i<N;i++)      {            int x=key[i][0],y=key[i][1];            m=T[y].size();             for (k=0;k<m;k++) addline(i<<1,hash[T[y][k]]);            m=T[x].size();            for (k=0;k<m;k++) addline(i<<1|1,hash[T[x][k]]);      }       memset(dfn,0,sizeof(dfn));      memset(instack,false,sizeof(instack));      while (!mystack.empty()) mystack.pop();      DfsIndex=tpnum=0;      for (i=0;i<(N<<1);i++)         if (!dfn[i]) tarjan(i);      for (i=0;i<N;i++)         if (tp[i<<1]==tp[i<<1|1]) return false;       return true;}int main(){             int N,M,i;       while (~scanf("%d%d",&N,&M) && N)      {              for (i=0;i<N;i++)               {                     scanf("%d%d",&key[i][0],&key[i][1]);                     hash[key[i][0]]=i<<1,hash[key[i][1]]=i<<1|1;              }              for (i=1;i<=M;i++) scanf("%d%d",&door[i][0],&door[i][1]);              int l=0,r=M+1,mid;              while (r-l>1)              {                     mid=l+r>>1;                     if (!_2sat(N,mid)) r=mid;                           else l=mid;              }              printf("%d\n",l);      }      return 0;}  


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 碎纸机轮不转了怎么办 轮滑鞋刀架螺丝圆了了怎么办 万朋商城2018年怎么办 超市盘点少了烟怎么办 歌华有线电视费用欠费好久怎么办 租房到期房东不退押金怎么办 个税申报错税局查出来怎么办 苹果手表抬腕唤醒失灵怎么办 在京东充电费充错了怎么办 进去了微商传销怎么办 喝完酒四肢酸痛睡不着怎么办 喝多了全身痛怎么办 喝完酒第二天浑身酸痛怎么办 鑫和陌车骗我钱怎么办 社会人加你qq怎么办 有人问你加qq怎么办 住酒店遇到被色情诈骗怎么办 怎么办我陷入感情骗局了 移动手机卡被强制停机怎么办 诚e赊套现被骗了怎么办 钻戒小了怎么办小窍门 爱用商城逾期了怎么办 工程骗局洗脑了怎么办 还网贷客服电话打不通怎么办 中信客服电话打不通怎么办 亚马逊客服电话打不通怎么办 安卓软件闪退怎么办? 吃鸡麦克风炸麦怎么办 美版iphone屏摔了怎么办 天地荣域四十后怎么办 淘宝拍下商品不付款怎么办 淘宝买东西取消订单淘金币怎么办 淘宝淘金币快过期了怎么办 公众号密码忘了怎么办 酷狗直播个入驻粉丝少怎么办 健康证预约显示未接收怎么办 在互惠车贷逾期怎么办 天天中彩票怎么登陆不了怎么办 正宇新商城不能提现怎么办 融e购买完不发货怎么办 婴儿肚子胀气肚脐凸出来怎么办