题意:
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 long using 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; }