一共有 \(K\) 场比赛,每场比赛有 \(n\) 种材料和 \(m\) 位评委。每种材料只能使用一次,可以用于制作该种材料对应的满式菜或汉式菜。每位评委都有喜爱的两种菜,只有选手做出这两种菜中的至少一种他才会满意。对每一场比赛判断是否有一种做菜方案使得所有评委满意。
2-SAT 裸题。
#include <cstdio>
#include <cstring>
#include <algorithm>
inline unsigned read(void){
unsigned res = 0; char ch = std::getchar();
while(ch < '0' || ch > '9')
ch = std::getchar();
while(ch >= '0' && ch <= '9')
res = res * 10 + ch - 48, ch = std::getchar();
return res;
}
const int MAXN = 1e2 + 19, MAXM = 1e3 + 19;
struct Edge{
int to, next;
}edge[MAXM << 2];
int cnt, head[MAXN << 2];
inline void add(int from, int to){
edge[++cnt].to = to;
edge[cnt].next = head[from];
head[from] = cnt;
}
int ind;
int dfn[MAXN << 2], low[MAXN << 2];
int stack[MAXN << 2], top, vist[MAXN << 2];
int color_cnt, color[MAXN << 2];
void dfs(int node){
dfn[node] = low[node] = ++ind;
stack[++top] = node; vist[node] = true;
for(int i = head[node]; i; i = edge[i].next)
if(!dfn[edge[i].to]){
dfs(edge[i].to);
low[node] = std::min(low[node], low[edge[i].to]);
}
else if(vist[edge[i].to])
low[node] = std::min(low[node], low[edge[i].to]);
if(dfn[node] == low[node]){
++color_cnt;
while(stack[top + 1] != node){
color[stack[top]] = color_cnt;
vist[stack[top]] = false;
--top;
}
}
}
int n, m;
char meal1[9], meal2[9];
int mt1, mt2;
bool tp1, tp2;
void init(void){
std::memset(head, 0, sizeof head);
cnt = 0;
ind = 0;
std::memset(dfn, 0, sizeof dfn);
std::memset(low, 0, sizeof low);
std::memset(stack, 0, sizeof stack);
top = 0;
color_cnt = 0;
}
int main(){
for(int T = read(); T; --T){
init();
n = read(), m = read();
for(int i = 1; i <= m; ++i){
std::scanf("%s%s", meal1, meal2);
std::sscanf(meal1 + 1, "%d", &mt1);
std::sscanf(meal2 + 1, "%d", &mt2);
tp1 = meal1[0] == 'm';
tp2 = meal2[0] == 'm';
add(mt1 * 2 - tp1 + n * 2, mt2 * 2 - tp2);
add(mt2 * 2 - tp2 + n * 2, mt1 * 2 - tp1);
}
for(int i = 1; i <= n; ++i){
add(i * 2, i * 2 - 1 + n * 2);
add(i * 2 - 1, i * 2 + n * 2);
}
for(int i = 1; i <= n * 4; ++i)
if(!dfn[i])
dfs(i);
for(int i = 1; i <= n * 2; ++i)
if(color[i] == color[i + n * 2]){
std::puts("BAD");
goto rep;
}
std::puts("GOOD");
rep:;
}
return 0;
}