题意
真不知道这道题说了这么多有什么用。
就是每种菜有m和h两种,然后只能取其中一个,然后有M条限制,表示取了前一个就不能取后一个了,然后求可不可行?
题解
看懂题意就是很裸的2-SAT了(虽然我题意说的一点都不清楚
//Suplex
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#define N 10000
using namespace std;
int T,n,m,cnt,t,tot,top,x,y,xx,yy,low[N],dfn[N],vet[N+N],Next[N+N],head[N];
int belong[N],stack[N+N],size[N],c[N];
void add_edge(int u,int v)
{
vet[++cnt]=v;Next[cnt]=head[u];head[u]=cnt;
}
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
inline int get()
{
char ch=getchar();
int x;
while(ch!='m' && ch!='h') ch=getchar();
if(ch=='m') x=read()*2;
else x=read()*2-1;
return x;
}
void tarjan(int u)
{
low[u]=dfn[u]=++tot;
c[u]=1;stack[++top]=u;
for(int i=head[u];i;i=Next[i]){
int v=vet[i];
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}else if(c[v]) low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u]){
int tmp=0;
t++;
while(tmp!=u){
tmp=stack[top--];
c[tmp]=0;
belong[tmp]=t;
size[t]++;
}
}
}
int main()
{
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
cnt=0;top=0;t=0;tot=0;
for(int i=1;i<=n+n;i++) head[i]=c[i]=low[i]=dfn[i]=0;
for(int i=1;i<=m;i++){
x=get();y=get();
if(x%2) xx=x++;else xx=x--;
if(y%2) yy=y++;else yy=y--;
add_edge(x,yy);add_edge(y,xx);
}
for(int i=1;i<=n+n;i++) if(!dfn[i]) tarjan(i);
bool flag=true;
for(int i=1;i<=n;i++) if(belong[i+i]==belong[i+i-1]){flag=false;break;}
if(flag) puts("GOOD");else puts("BAD");
}
return 0;
}