HDOJ 4115 - Eliminate the Conflict 构图2-sat...思维不能乱~!!

来源:互联网 发布:做优化发展环境维护人 编辑:程序博客网 时间:2024/04/28 08:47

            题意:

                     Bob和Alice划拳比赛~~Alice掌握了Bob的出招规律~知道Bob每轮出什么..而Bob则规定了Alice某些对轮出的必须相同或者必须不同...Alice如果要获胜..必须所有的局不败...问Alice有无获胜的策略...

            题解:

                     这题乍一看和2-sat无关系......要不是放在了2-sat的专题..我也不会往2-sat上套..囧...经验经验!!

                     要保证Alice一直不败..那么每轮要么赢要么赢...又知道了Bob每轮出的是什么...可以推断出每轮出什么赢.出什么平..根据给的相同不相同构造2-sat模型...我是分为了两大类情况...首先是这两个必须相同还是不相同..然后是Bob这两轮的出招是相等还是不相等...为了处理方便..当两轮不想等的时候...调整为Bob的第X轮出招是赢Bob第Y轮出招的...模型建好..剩下的就是裸的tarjan判可行性了...


Program:

#include<iostream>#include<stdio.h>#include<cmath>#include<queue>#include<stack>#include<string.h>#include<map>#include<set>#include<algorithm>#define oo 1000000007#define MAXN 20005<<1#define MAXM 100000<<2#define ll long longusing namespace std; struct node{       int y,next;}line[MAXM];int Lnum,_next[MAXN],a[MAXN],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)  {         mystack.push(x),instack[x]=true;         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 judge(int N){       for (int i=0;i<N;i++)          if (tp[i<<1]==tp[i<<1|1]) return false;       return true;}int main(){                 int T,cases,i,N,M;       scanf("%d",&T);       for (cases=1;cases<=T;cases++)       {                scanf("%d%d",&N,&M);                for (i=0;i<N;i++) scanf("%d",&a[i]);                Lnum=0,memset(_next,0,sizeof(_next));                while (M--)  // x<<1 赢... x<<1|1 平                 {                        int tp,x,y;                        scanf("%d%d%d",&x,&y,&tp),x--,y--;                        if (a[x]!=a[y] && (a[x]-a[y]+3)%3!=1) swap(x,y); //调整下..减少代码量                        if (!tp)                        {                              if (a[x]==a[y])                               {                                   addline(x<<1,y<<1),addline(x<<1|1,y<<1|1);                                   addline(y<<1,x<<1),addline(y<<1|1,x<<1|1);                              }else                              {                                   addline(x<<1,x<<1|1),addline(x<<1|1,y<<1);                                   addline(y<<1,x<<1|1),addline(y<<1|1,y<<1);                              }                        }else                        {                              if (a[x]==a[y])                               {                                    addline(x<<1,y<<1|1),addline(x<<1|1,y<<1);                                   addline(y<<1,x<<1|1),addline(y<<1|1,x<<1);                              }else                                   addline(x<<1|1,y<<1|1),addline(y<<1,x<<1);                        }                }                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);                printf("Case #%d: ",cases);                if (!judge(N)) printf("no\n");                       else  printf("yes\n");       }       return 0;} 


原创粉丝点击