=== ===
这里放传送门
=== ===
题解
可以发现每种食材要么选m要么选h,并且因为每个评委的要求必须至少满足一个,那么就会出现一些例如食材A选了m,食材B就必须选h这样的限制。那么这就是一个2-SAT可行性判断问题。
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#define clear(x)(memset(x,0,sizeof(x)))
using namespace std;
int T,n,m,p[
210],a[
2010],nxt[
2010],low[
210],w[
210],st[
210],top,pos[
210],tot,cnt;
bool ext[
210],flag;
int rev(
int x){
return (x<=n)?x+n:x-n;}
int get(){
char c=getchar();
int x=
0,dlt;
while (c!=
'm'&&c!=
'h') c=getchar();
dlt=(c==
'm')?
0:n;
c=getchar();
while (c<
'0'||c>
'9') c=getchar();
while (c>=
'0'&&c<=
'9'){
x=x*
10+c-
'0';c=getchar();
}
return x+dlt;
}
void add(
int x,
int y){
tot++;a[tot]=y;nxt[tot]=p[x];p[x]=tot;
}
void Tarjan(
int u){
low[u]=w[u]=++tot;
st[++top]=u;ext[u]=
true;
for (
int i=p[u];i!=
0;i=nxt[i])
if (w[a[i]]==
0){
Tarjan(a[i]);
low[u]=min(low[u],low[a[i]]);
}
else if (ext[a[i]]==
true) low[u]=min(low[u],w[a[i]]);
if (low[u]==w[u]){
int v;++cnt;
do{
v=st[top--];pos[v]=cnt;ext[v]=
false;
}
while (v!=u);
}
}
int main()
{
scanf(
"%d",&T);
for (
int wer=
1;wer<=T;wer++){
clear(p);clear(w);clear(low);
clear(ext);tot=cnt=top=flag=
0;
scanf(
"%d%d",&n,&m);
for (
int i=
1;i<=m;i++){
int v1=get(),v2=get();
add(rev(v1),v2);
add(rev(v2),v1);
}
for (
int i=
1;i<=
2*n;i++)
if (w[i]==
0) Tarjan(i);
for (
int i=
1;i<=n;i++)
if (pos[i]==pos[rev(i)]){
flag=
true;
break;
}
if (flag==
true)
printf(
"BAD\n");
else printf(
"GOOD\n");
}
return 0;
}
转载请注明原文地址: https://ju.6miu.com/read-36897.html