题目链接
https://www.lydsy.com/JudgeOnline/problem.php?id=1823
思路
每种材料只能做成满或汉两种方式,因此可以用2-sat简单解决。
代码
#include <cstdio>
#include <cstring>
#include <algorithm>
const int maxn=200;
const int maxm=2000;
int read()
{
int x=0,f=1;
char ch=getchar();
while((ch<'0')||(ch>'9'))
{
if(ch=='-')
{
f=-f;
}
ch=getchar();
}
while((ch>='0')&&(ch<='9'))
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
int pre[maxm+10],now[maxn+10],son[maxm+10],tot;
int belong[maxn+10],dfn[maxn+10],low[maxn+10],opp[maxn+10];
int top,stack[maxn+10],k,n,m,cnt,cntl,instack[maxn+10];
inline int trans(char c,int v)
{
return (v<<1)-(c=='m');
}
inline int ins(int a,int b)
{
pre[++tot]=now[a];
now[a]=tot;
son[tot]=b;
return 0;
}
int tarjan(int u)
{
stack[++top]=u;
instack[u]=1;
dfn[u]=low[u]=++cnt;
int j=now[u];
while(j)
{
int v=son[j];
if(!dfn[v])
{
tarjan(v);
low[u]=std::min(low[u],low[v]);
}
else if(instack[v])
{
low[u]=std::min(low[u],dfn[v]);
}
j=pre[j];
}
if(dfn[u]==low[u])
{
int w=0;
++cntl;
while(w!=u)
{
w=stack[top--];
instack[w]=0;
belong[w]=cntl;
}
}
return 0;
}
int main()
{
k=read();
while(k--)
{
memset(now,0,sizeof now);
memset(belong,0,sizeof belong);
memset(dfn,0,sizeof dfn);
tot=cnt=cntl=0;
n=read();
m=read();
for(int i=1; i<=n; ++i)
{
opp[i*2-1]=i*2;
opp[i*2]=i*2-1;
}
for(int i=1; i<=m; ++i)
{
char c=getchar();
while((c<'a')||(c>'z'))
{
c=getchar();
}
int a=read();
char d=getchar();
while((d<'a')||(d>'z'))
{
d=getchar();
}
int b=read();
int x=trans(c,a),y=trans(d,b);
ins(opp[x],y);
ins(opp[y],x);
}
for(int i=1; i<=n<<1; ++i)
{
if(!dfn[i])
{
tarjan(i);
}
}
int flag=0;
for(int i=1; i<=n; ++i)
{
if(belong[i*2-1]==belong[i*2])
{
puts("BAD");
flag=1;
break;
}
}
if(!flag)
{
puts("GOOD");
}
}
return 0;
}