满汉全席
洛谷
发现不成立的情况是一种食材要被做成两种方法
也就是说:如果牛肉要被一号评委作为满式,被X号评委做成汉式
则我们将满式牛肉连向X号评委希望的另一种菜肴
将汉式牛肉连向一号评委希望的另一种菜肴
(因为如果选了汉式牛肉,则满式牛肉不可选
而选了另一种菜肴,却不一定必须要选汉式牛肉)
我说清楚了吧QAQ
#include<bits/stdc++.h>
#define re return
#define inc(i,l,r) for(int i=l;i<=r;++i)
const int maxn=205,maxm=2005;
using namespace std;
template<typename T>inline void rd(T&x)
{
char c;bool f=0;
while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
x=c^48;
while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
if(f)x=-x;
}
int n,m,tot,k,dfn[maxn],low[maxn],col,belong[maxn],hd[maxn];
vector<int>G[maxn];
vector<int>::iterator iter;
struct node{
int to,nt;
}e[maxm<<1];
stack<int>s;
inline void tarjan(int x)
{
s.push(x);
dfn[x]=low[x]=++tot;
for(int i=hd[x];i;i=e[i].nt)
{
int v=e[i].to;
if(!dfn[v])
{
tarjan(v);
low[x]=min(low[v],low[x]);
}
else if(!belong[v])low[x]=min(low[x],dfn[v]);
}
if(dfn[x]==low[x])
{
int v=-1;++col;
while(v!=x)
{
v=s.top();
s.pop();
belong[v]=col;
}
}
}
inline void add(int x,int y)
{
e[++k]=(node){y,hd[x]};hd[x]=k;
}
char s1[20];
inline int vivi()
{
int x=0,cnt=0;
while(s1[++cnt]>='0'&&s1[cnt]<='9')x=x*10+(s1[cnt]^48);
re x;
}
int main()
{
int x,y,T;
// freopen("in.txt","r",stdin);
rd(T);
while(T--)
{
k=tot=0;
rd(n);rd(m);
inc(i,1,n<<1)hd[i]=dfn[i]=belong[i]=0;
inc(i,1,m)
{
scanf("%s",s1);
x=(s1[0]=='m')*n+vivi();
scanf("%s",s1);
y=(s1[0]=='m')*n+vivi();
G[x].push_back(y);
G[y].push_back(x);
}
inc(i,1,n)
{
for(iter=G[i].begin();iter!=G[i].end();iter++)
add(i+n,*iter);
G[i].clear();
for(iter=G[i+n].begin();iter!=G[i+n].end();iter++)
add(i,*iter);
G[i+n].clear();
}
inc(i,1,n<<1)
if(!dfn[i])tarjan(i);
int f=0;
inc(i,1,n)
if(belong[i]==belong[i+n])
{
f=1;
break;
}
if(!f)printf("GOOD\n");
else printf("BAD\n");
}
re 0;
}