hihoCoder #1467 : 2-SAT·hihoCoder音乐节
題目鏈接
描述
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
思路
2-SAT問題:一共有NNN個選項MMM個要求,求一種滿足所有約束條件的方案
- 首先把NNN個選項拆成2N2N2N個分別表示相反的狀態
- 然后根據約束條件建圖,例如(a(a(a or b)b)b) 我們就建這樣兩個邊:?a?a?a–>bbb 和?b?b?b–>aaa 表示當aaa不成立時bbb一定要成立 或者 bbb不成立aaa一定要成立,這樣就能保證至少有一個條件滿足,而且能能夠盡可能的滿足多個約束條件
- 矛盾情況就是,最后求得的一個聯通分量里面包含有一個點的兩個狀態(這個狀態既要滿足又要不滿足)就是矛盾
我把輸入的數據按照字符串來處理剛開始一直WA,我在判斷數字的時候只截取了S[1],編號可是100啊!
#include <bits/stdc++.h> #define LL long long #define P pair<int, int> #include <time.h> #define lowbit(x) (x & -x) #define mem(a, b) memset(a, b, sizeof(a)) #define rep(i, a, n) for (int i = a; i <= n; ++i) const int maxn = 305; #define mid ((l + r) >> 1) #define lc rt<<1 #define rc rt<<1|1 using namespace std; int tot, len, ts; int low[maxn], dfn[maxn], Stack[maxn], inStack[maxn], belong[maxn]; vector<int> g[maxn];void tarjan(int x) {Stack[len++] = x;inStack[x] = 1;low[x] = dfn[x] = ++ts;for (int i = 0; i < (int)g[x].size(); ++i) {int y = g[x][i];if (!dfn[y]) tarjan(y), low[x] = min(low[x], low[y]);else if (inStack[y]) low[x] = min(low[x], low[y]);}if (dfn[x] == low[x]) {tot++;int top;do{top = Stack[--len];inStack[top] = 0;belong[top] = tot;}while (top != x);} }int main() { #ifndef ONLINE_JUDGE// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout); #endifios::sync_with_stdio(false);cin.tie(0); cout.tie(0);map<char, int> mi;mi['m'] = 0;int T;scanf("%d", &T);int n, m;while (T--) {scanf("%d %d", &n, &m);len = ts = tot = 0;mem(inStack, 0);mem(low, 0);mem(Stack, 0);mem(belong, 0);mem(dfn, 0);for (int i = 0; i < maxn; ++i) g[i].clear();mi['h'] = n; for (int i = 0; i < m; ++i) {int l, r, l1, r1; // l,r 表示一個約束條件 l1,r1 分表表示反狀態char x, y;scanf(" %c%d %c%d ", &x, &l, &y, &r);l += mi[x];r += mi[y];l1 = l > n ? l-n : l+n;r1 = r > n ? r-n : r+n;// 建圖g[l1].push_back(r);g[r1].push_back(l);} // tarjan for (int i = 1; i<= n*2; ++i) {if (!dfn[i]) tarjan(i);}int flag = 0;for (int i = 1; i <= n; ++i) {if (belong[i] == belong[i+n]) flag = 1;}puts(flag ? "BAD" : "GOOD");}return 0; }總結
以上是生活随笔為你收集整理的hihoCoder #1467 : 2-SAT·hihoCoder音乐节的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HDU 4685 Prince and
- 下一篇: HDU-6470 Count (构造矩阵