Description
满汉全席是中国最丰盛的宴客菜肴,有许多种不同的材料透过满族或是汉族的料理方式,呈现在數量繁多的菜色之中。由于菜色众多而繁杂,只有极少數博学多闻技艺高超的厨师能够做出满汉全席,而能够烹饪出经过专家认证的满汉全席,也是中国厨师最大的荣誉之一。 世界满汉全席协会是由能够料理满汉全席的专家厨师们所组成,而他们之间还细分为许多不同等级的厨师。为了招收新进的厨师进入世界满汉全席协会,将于近日举办满汉全席大赛,协会派遣许多会员当作评审员,为的就是要在參赛的厨师之中,找到满汉料理界的明日之星。 大会的规则如下:每位參赛的选手可以得到n 种材料,选手可以自由选择用满式或是汉式料理将材料当成菜肴。大会的评审制度是:共有m 位评审员分别把关。每一位评审员对于满汉全席有各自独特的見解,但基本见解是,要有兩样菜色作为满汉全席的标志。如某评审认为,如果没有汉式东坡肉跟满式的涮羊肉锅,就不能算是满汉全席。但避免过于有主見的审核,大会规定一个评审员除非是在认为必备的两样菜色都没有做出來的狀况下,才能淘汰一位选手,否则不能淘汰一位參赛者。换句话說,只要參赛者能在这兩种材料的做法中,其中一个符合评审的喜好即可通过该评审的审查。如材料有猪肉,羊肉和牛肉时,有四位评审员的喜好如下表: 评审一 评审二 评审三 评审四 满式牛肉 满式猪肉 汉式牛肉 汉式牛肉 汉式猪肉 满式羊肉 汉式猪肉 满式羊肉 如參赛者甲做出满式猪肉,满式羊肉和满式牛肉料理,他将无法满足评审三的要求,无法通过评审。而參赛者乙做出汉式猪肉,满式羊肉和满式牛肉料理,就可以满足所有评审的要求。 但大会后來发现,在这样的制度下如果材料选择跟派出的评审员没有特别安排好的话,所有的參赛者最多只能通过部分评审员的审查而不是全部,所以可能会发生没有人通过考核的情形。如有四个评审员喜好如下表时,则不論參赛者采取什么样的做法,都不可能通过所有评审的考核: 评审一 评审二 评审三 评审四 满式羊肉 满式猪肉 汉式羊肉 汉式羊肉 汉式猪肉 满式羊肉 汉式猪肉 满式猪肉 所以大会希望有人能写一个程序來判断,所选出的m 位评审,会不会发生 没有人能通过考核的窘境,以便协会组织合适的评审团。
Solution
2-SAT水题,连方案都不需要输出233
对于每个菜建m,h两个点,对于输入的c1 n1 c2 n2(c为h/m,n为编号),从n1[c1^1]向n2[c2]连边,从n2[c2^1]向n1[c1]连边,跑Tarjan即可。
Code
/************************************************
* Au: Hany01
* Date: May 31st, 2018
* Prob: [BZOJ1823][JSOI2010] 满汉全席
* Email: hany01@foxmail.com
************************************************/
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
#define File(a) freopen(a".in", "r", stdin), freopen(a".out", "w", stdout)
#define rep(i, j) for (register int i = 0, i##_end_ = (j); i < i##_end_; ++ i)
#define For(i, j, k) for (register int i = (j), i##_end_ = (k); i <= i##_end_; ++ i)
#define Fordown(i, j, k) for (register int i = (j), i##_end_ = (k); i >= i##_end_; -- i)
#define Set(a, b) memset(a, b, sizeof(a))
#define Cpy(a, b) memcpy(a, b, sizeof(a))
#define x first
#define y second
#define pb(a) push_back(a)
#define mp(a, b) make_pair(a, b)
#define ALL(a) (a).begin(), (a).end()
#define SZ(a) ((int)(a).size())
#define INF (0x3f3f3f3f)
#define INF1 (2139062143)
#define Mod (1000000007)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define y1 wozenmezhemecaia
template <typename T> inline bool chkmax(T &a, T b) { return a < b ? a = b, 1 : 0; }
template <typename T> inline bool chkmin(T &a, T b) { return b < a ? a = b, 1 : 0; }
inline int read()
{
register int _, __; register char c_;
for (_ = 0, __ = 1, c_ = getchar(); c_ < '0' || c_ > '9'; c_ = getchar()) if (c_ == '-') __ = -1;
for ( ; c_ >= '0' && c_ <= '9'; c_ = getchar()) _ = (_ << 1) + (_ << 3) + (c_ ^ 48);
return _ * __;
}
const int maxn = 205, maxm = 2005;
int e, beg[maxn], nex[maxm], v[maxm], stk[maxn], top, isin[maxn], cnt, co[maxn], dfn[maxn], low[maxn], clk;
inline void add(int uu, int vv) { v[++ e] = vv, nex[e] = beg[uu], beg[uu] = e; }
inline int getc()
{
register char c = getchar();
for ( ; c != 'h' && c != 'm'; c = getchar());
return c == 'h' ? 0 : 1;
}
void dfs(int u)
{
dfn[u] = low[u] = ++ clk, stk[++ top] = u, isin[u] = 1;
for (register int i = beg[u]; i; i = nex[i])
if (!dfn[v[i]]) dfs(v[i]), chkmin(low[u], low[v[i]]);
else if (isin[v[i]]) chkmin(low[u], dfn[v[i]]);
if (low[u] == dfn[u]) {
++ cnt;
do co[stk[top]] = cnt, isin[stk[top]] = 0; while (stk[top --] != u);
}
}
int main()
{
#ifdef hany01
File("bzoj1823");
#endif
static int n, m, t1, t2, n1, n2;
for (static int T = read(); T --; ) {
n = read(), m = read(), e = 1, Set(beg, 0), Set(dfn, 0), clk = 0;
For(i, 1, m) t1 = getc(), n1 = read(), t2 = getc(), n2 = read(), add(n1 << 1 | (t1 ^ 1), n2 << 1 | t2), add(n2 << 1 | (t2 ^ 1), n1 << 1 | t1);
For(i, 2, n << 1 | 1) if (!dfn[i]) dfs(i);
int err = 0;
For(i, 1, n) if (co[i << 1] == co[i << 1 | 1]) { err = 1; break; }
puts(err ? "BAD" : "GOOD");
}
return 0;
}
//日日思君不见君,共饮长江水。
// -- 李之仪《卜算子·我住长江头》