题目:
题解:
满式和汉式,两种选择,然后限制是AB不能同时不取,那么我们要添加的边就是
A′−>B
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int N=205;
const int M=2005;
int tot,point[N],v[M],nxt[M],low[N],dfn[N],nn,stack[N],top,id,belong[N];bool vis[N];
void addline(int x,int y){++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y;}
void tarjan(int x)
{
low[x]=dfn[x]=++nn; vis[x]=1; stack[++top]=x;
for (int i=point[x];i;i=nxt[i])
if (!dfn[v[i]])
{
tarjan(v[i]); low[x]=min(low[x],low[v[i]]);
}
else if (vis[v[i]]) low[x]=min(low[x],dfn[v[i]]);
if (low[x]==dfn[x])
{
int now=0;++id;
while (now!=x)
{
now=stack[top--];
vis[now]=0;
belong[now]=id;
}
}
}
int main()
{
int T,n,m;scanf("%d",&T);
while (T--)
{
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
top=0; id=0; tot=0;memset(point,0,sizeof(point));
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++)//x汉式 x+n满式
{
char s1[20],s2[20];int x=0,y=0,z,l;
scanf("%s%s",s1,s2);
int l1=strlen(s1),l2=strlen(s2);
for (int j=1;j<l1;j++) x=x*10+s1[j]-'0';
for (int j=1;j<l2;j++) y=y*10+s2[j]-'0';
if (s1[0]=='m') z=1;else z=0;
if (s2[0]=='m') l=1;else l=0;
addline(x+(!z)*n,y+l*n);
addline(y+(!l)*n,x+z*n);
}
for (int i=1;i<=2*n;i++)
if (!dfn[i]) tarjan(i);
bool fff=0;
for (int i=1;i<=n;i++)
if (belong[i]==belong[i+n]) {fff=1;break;}
if (fff) printf("BAD\n");else printf("GOOD\n");
}
}