結果
問題 | No.1365 [Cherry 1st Tune] Whose Fault? |
ユーザー | iaNTU |
提出日時 | 2021-01-14 17:31:24 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 4,554 bytes |
コンパイル時間 | 2,086 ms |
コンパイル使用メモリ | 214,772 KB |
実行使用メモリ | 13,884 KB |
最終ジャッジ日時 | 2024-06-09 06:41:49 |
合計ジャッジ時間 | 6,256 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | WA | - |
testcase_01 | WA | - |
testcase_02 | WA | - |
testcase_03 | WA | - |
testcase_04 | TLE | - |
testcase_05 | -- | - |
testcase_06 | -- | - |
testcase_07 | -- | - |
testcase_08 | -- | - |
testcase_09 | -- | - |
testcase_10 | -- | - |
testcase_11 | -- | - |
testcase_12 | -- | - |
testcase_13 | -- | - |
testcase_14 | -- | - |
testcase_15 | -- | - |
testcase_16 | -- | - |
testcase_17 | -- | - |
testcase_18 | -- | - |
testcase_19 | -- | - |
testcase_20 | -- | - |
testcase_21 | -- | - |
testcase_22 | -- | - |
testcase_23 | -- | - |
testcase_24 | -- | - |
testcase_25 | -- | - |
testcase_26 | -- | - |
testcase_27 | -- | - |
testcase_28 | -- | - |
testcase_29 | -- | - |
testcase_30 | -- | - |
testcase_31 | -- | - |
testcase_32 | -- | - |
testcase_33 | -- | - |
testcase_34 | -- | - |
testcase_35 | -- | - |
testcase_36 | -- | - |
testcase_37 | -- | - |
testcase_38 | -- | - |
testcase_39 | -- | - |
testcase_40 | -- | - |
testcase_41 | -- | - |
testcase_42 | -- | - |
testcase_43 | -- | - |
testcase_44 | -- | - |
testcase_45 | -- | - |
ソースコード
// Compile flags -Wall -Wextra -Wshadow -D_GLIBCXX_ASSERTIONS -DDEBUG -ggdb3 -fmax-errors=2 #include <bits/stdc++.h> using namespace std; #define PB push_back #define F first #define S second #define MP make_pair #define MTP make_tuple typedef long long int ll; ll ABS(ll n) {return n >= 0 ? n : -n;} constexpr int kN = int(4E3 + 10); // constexpr int kMod = 998244353; // constexpr int kInf = 0x3f3f3f3f // constexpr ll kInf = 0x3f3f3f3f3f3f3f3f; int a[kN], b[kN], c[kN], p[kN], ans[kN], dep[kN], low[kN], scc[kN]; bitset<kN> is_big, in, went; bitset<26> bs[kN]; vector<int> big_edge[kN], small_edge[kN], colors[kN], new_colors[kN], graph[kN]; vector<int> big, small; stack<int> st; int Find(int n) {return n == p[n] ? n : p[n] = Find(p[n]);} void Merge(int l, int r) { l = Find(l), r = Find(r); p[r] = l; bs[l] &= bs[r]; return ; } void tarjan(int cur) { static int t = 0, scccnt = 0; st.push(cur); low[cur] = dep[cur] = ++t; in[cur] = went[cur] = true; for (int i : graph[cur]) { if (!went[i]) tarjan(i); if (in[i]) low[cur] = min(low[cur], low[i]); } if (low[cur] == dep[cur]) { while (st.top() != cur) { in[st.top()] = false; scc[st.top()] = scccnt; st.pop(); } // st.top() == cur in[st.top()] = false; scc[st.top()] = scccnt++; st.pop(); } return ; } bool check() { // make all small degree 2 queue<int> q; for (int i : small) new_colors[i].clear(); for (int i : small) ans[i] = -1; for (int i : small) { for (int color : colors[i]) { for (int j : big) if (ans[j] == color) goto check_Bad; check_Good: new_colors[i].PB(color); check_Bad: continue; } if (int(new_colors[i].size()) == 0) return false; else if (int(new_colors[i].size()) == 1) q.push(i); } while (!q.empty()) { int cur = q.front(); q.pop(); ans[cur] = new_colors[cur][0]; for (int i : small_edge[cur]) { vector<int> tmp; swap(tmp, new_colors[i]); for (int color : tmp) if (color != ans[cur]) new_colors[i].PB(color); if (int(tmp.size()) > int(new_colors[i].size())) { if (new_colors[i].empty()) return false; else q.push(i); } } } // int(new_colors[i].size()) == 2 for (int i : small) if (ans[i] == -1) { graph[i << 1].clear(); graph[i << 1 | 1].clear(); } for (int i : small) if (ans[i] == -1) { for (int j : small_edge[i]) if (ans[j] == -1) { for (int x = 0; x < 2; x++) for (int y = 0; y < 2; y++) if (new_colors[i][x] == new_colors[j][y]) { graph[i << 1 | x].PB(j << 1 | (y ^ 1)); graph[j << 1 | y].PB(i << 1 | (x ^ 1)); } } } in.reset(); went.reset(); for (int i : small) if (ans[i] == -1) { if (!went[i << 1]) tarjan(i << 1); if (!went[i << 1 | 1]) tarjan(i << 1 | 1); if (scc[i << 1] == scc[i << 1 | 1]) return false; } for (int i : small) if (ans[i] == -1) { if (scc[i << 1] < scc[i << 1 | 1]) ans[i] = new_colors[i][0]; else ans[i] = new_colors[i][1]; } return true; } bool dfs(int idx) { if (idx >= int(big.size())) return check(); else { for (int color : colors[big[idx]]) { for (int i : big_edge[big[idx]]) if (ans[i] == color) goto Bad; Good: ans[big[idx]] = color; if (dfs(idx + 1)) return true; Bad: ans[big[idx]] = -1; } return false; } } int main() { //ios::sync_with_stdio(false); //cin.tie(0); //freopen("file_name", "r", stdin); //freopen("file_name", "w", stdout); //fstream input, output; //input.open("file_name", ios::in); //output.open("file_name", ios::out); int n, m; cin >> n >> m; for (int i = 1; i <= m; i++) cin >> a[i] >> b[i] >> c[i]; for (int i = 1; i <= n; i++) { int t; cin >> t; for (int j = 1; j <= t; j++) { char k; cin >> k; bs[i][k - 'a'] = true; } } for (int i = 1; i <= n; i++) p[i] = i; for (int i = 1; i <= m; i++) if (c[i] == 1) Merge(a[i], b[i]); for (int i = 1; i <= n; i++) if (p[i] == i && bs[i].none()) goto Fault; for (int i = 1; i <= n; i++) if (p[i] == i) { if (bs[i].count() >= 3) big.PB(i); else small.PB(i); } for (int i : big) is_big[i] = true; for (int i = 1; i <= m; i++) if (c[i] == 0) { int l = Find(a[i]), r = Find(b[i]); if (is_big[r]) big_edge[l].PB(r); else small_edge[l].PB(r); if (is_big[l]) big_edge[r].PB(l); else small_edge[r].PB(l); } for (int i = 1; i <= n; i++) if (p[i] == i) for (int j = 0; j < 26; j++) if (bs[i][j]) colors[i].PB(j); for (int i : big) ans[i] = -1; if (!dfs(0)) goto Fault; for (int i = 1; i <= n; i++) cout << char(ans[Find(i)] + 'a'); cout << "\n"; return 0; Fault: cout << "Fault\n"; return 0; //input.close(); //output.close(); }