2-SAT·hihoCoder音乐节
2-SAT·hihoCoder音乐节
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
hihoCoder音乐节由hihoCoder赞助商大力主办,邀请了众多嘉宾和知名乐队参与演出。
音乐会分为上午、下午两场进行,主办方指定了n首歌让乐队进行演唱。每首歌只会被演唱一次,要么在上午要么在下午。
参加音乐会的嘉宾们对于歌曲的演唱时间有一些要求。具体来说,每位嘉宾会指定两首歌曲的演唱时间(上午或者下午)。如果最后实际的演出安排中,两首歌都没有达到嘉宾的要求,那么嘉宾就会对音乐节不滿意。如嘉宾A的要求是上午《我的滑板鞋》和下午《忐忑》,而最后的演出中上午没有《我的滑板鞋》只有《忐忑》,下午没有《忐忑》只有《我的滑板鞋》,那么嘉宾A是不满意的。
音乐节主办方自然希望使所有嘉宾满意,但主办方后来发现有可能不存在一种歌曲的安排方案满足所有嘉宾,所以他们希望你判断一下这种情况是否会发生。
输入
输入第一行包含一个数字 K,代表K组数据。(K≤50)
对于每一组数据,第一行包含两个非负整数n和m(n≤100,m≤1000),代表有n首歌和m位嘉宾。
为了方便我们给予歌编号,编号分别从1 到n。接下的m行,每行都代表对应的嘉宾的喜好由一个英文字母(m或h)跟一个数字代表,如m1 代表这个评审喜欢第1首歌上午进行,而h2代表这个评审员喜欢第2首歌下午进行。
输出
对于每一组数据,输出一行,如果能满足所有嘉宾的情况,输出GOOD;否则输出BAD。
- 样例输入
-
2 3 4 m3 h1 m1 m2 h1 h3 h3 m2 2 4 h1 m2 m2 m1 h1 h2 m1 h2
- 样例输出
GOOD
BAD
- 分析:对每首歌建两个点,本别表示早上和下午演奏,然后建立有向图;
- 若嘉宾要求a||b,则建边¬a->b,¬b->a,最后求强连通分量;
- 若存在a与¬a在同一个强连通分量,则不可,否则有解;
- 代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <climits> #include <cstring> #include <string> #include <set> #include <bitset> #include <map> #include <queue> #include <stack> #include <vector> #define rep(i,m,n) for(i=m;i<=n;i++) #define mod 1000000007 #define inf 0x3f3f3f3f #define vi vector<int> #define pb push_back #define mp make_pair #define fi first #define se second #define ll long long #define pi acos(-1.0) #define pii pair<int,int> #define sys system("pause") const int maxn=2e2+10; using namespace std; inline ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);} inline ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}return f;} inline void umax(ll &p,ll q){if(p<q)p=q;} inline void umin(ll &p,ll q){if(p>q)p=q;} inline ll read() { ll x=0;int f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,m,k,t,pre[maxn],link[maxn],sccno[maxn],dfs_clock,scc_cnt,cas; vi e[maxn]; stack<int>s; char a[10],b[10]; void dfs(int u) { pre[u]=link[u]=++dfs_clock; s.push(u); for(int x:e[u]) { if(!pre[x]) { dfs(x); link[u]=min(link[u],link[x]); } else if(!sccno[x]) { link[u]=min(link[u],pre[x]); } } if(link[u]==pre[u]) { scc_cnt++; while(true) { int x=s.top(); s.pop(); sccno[x]=scc_cnt; if(x==u)break; } } } void find_scc(int n) { dfs_clock=scc_cnt=0; memset(sccno,0,sizeof(sccno)); memset(pre,0,sizeof(pre)); for(int i=0;i<2*n;i++) if(!pre[i])dfs(i); } inline int gao(char *p){int q=0,j=0;while(p[j])q=q*10+p[j]-'0',j++;return q;} int main() { int i,j; t=read(); while(t--) { n=read(),m=read(); while(m--) { scanf("%s%s",a,b); int fr=(gao(a+1)-1)*2,to=(gao(b+1)-1)*2; if(a[0]=='h')fr++;if(b[0]=='h')to++; e[fr^1].pb(to),e[to^1].pb(fr); } find_scc(n); for(i=0;i<2*n;i+=2)if(sccno[i]==sccno[i^1]){puts("BAD");break;} if(i==2*n)puts("GOOD"); rep(i,0,2*n-1)e[i].clear(); } return 0; }