結果
問題 | No.470 Inverse S+T Problem |
ユーザー | kimiyuki |
提出日時 | 2016-12-19 16:59:51 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 17 ms / 2,000 ms |
コード長 | 3,587 bytes |
コンパイル時間 | 1,784 ms |
コンパイル使用メモリ | 109,504 KB |
実行使用メモリ | 6,528 KB |
最終ジャッジ日時 | 2024-06-01 22:26:13 |
合計ジャッジ時間 | 2,509 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 1 ms
5,376 KB |
testcase_02 | AC | 2 ms
5,376 KB |
testcase_03 | AC | 1 ms
5,376 KB |
testcase_04 | AC | 2 ms
5,376 KB |
testcase_05 | AC | 2 ms
5,376 KB |
testcase_06 | AC | 17 ms
6,528 KB |
testcase_07 | AC | 16 ms
6,400 KB |
testcase_08 | AC | 17 ms
6,400 KB |
testcase_09 | AC | 2 ms
5,376 KB |
testcase_10 | AC | 2 ms
5,376 KB |
testcase_11 | AC | 2 ms
5,376 KB |
testcase_12 | AC | 2 ms
5,376 KB |
testcase_13 | AC | 2 ms
5,376 KB |
testcase_14 | AC | 2 ms
5,376 KB |
testcase_15 | AC | 1 ms
5,376 KB |
testcase_16 | AC | 1 ms
5,376 KB |
testcase_17 | AC | 2 ms
5,376 KB |
testcase_18 | AC | 2 ms
5,376 KB |
testcase_19 | AC | 2 ms
5,376 KB |
testcase_20 | AC | 2 ms
5,376 KB |
testcase_21 | AC | 2 ms
5,376 KB |
testcase_22 | AC | 2 ms
5,376 KB |
testcase_23 | AC | 2 ms
5,376 KB |
testcase_24 | AC | 2 ms
5,376 KB |
testcase_25 | AC | 1 ms
5,376 KB |
testcase_26 | AC | 2 ms
5,376 KB |
testcase_27 | AC | 2 ms
5,376 KB |
testcase_28 | AC | 3 ms
5,376 KB |
testcase_29 | AC | 2 ms
5,376 KB |
testcase_30 | AC | 2 ms
5,376 KB |
ソースコード
#include <iostream> #include <vector> #include <algorithm> #include <map> #include <cassert> #define repeat(i,n) for (int i = 0; (i) < int(n); ++(i)) #define repeat_from(i,m,n) for (int i = (m); (i) < int(n); ++(i)) using namespace std; struct strongly_connected_components { static pair<int,vector<int> > decompose(vector<vector<int> > const & g) { // adjacent list strongly_connected_components scc(g); return { scc.k, scc.c }; } private: int n; vector<vector<int> > to, from; explicit strongly_connected_components(vector<vector<int> > const & g) : n(g.size()), to(g), from(n) { repeat (i,n) for (int j : to[i]) from[j].push_back(i); decompose(); } vector<bool> used; vector<int> vs; void dfs(int i) { used[i] = true; for (int j : to[i]) if (not used[j]) dfs(j); vs.push_back(i); } int k; // number of scc vector<int> c; // i-th vertex in g is in c_i-th vertex in scc-decomposed g void rdfs(int i) { used[i] = true; c[i] = k; for (int j : from[i]) if (not used[j]) rdfs(j); } void decompose() { used.clear(); used.resize(n, false); repeat (i,n) if (not used[i]) dfs(i); used.clear(); used.resize(n, false); k = 0; c.resize(n); reverse(vs.begin(), vs.end()); for (int i : vs) if (not used[i]) { rdfs(i); k += 1; } } }; vector<bool> twosat(int n, vector<pair<int, int> > const & cnf) { vector<vector<int> > g(2*n); auto i = [&](int x) { assert (x != 0 and abs(x) <= n); return x > 0 ? x-1 : n-x-1; }; for (auto it : cnf) { int x, y; tie(x, y) = it; // x or y g[i(- x)].push_back(i(y)); // not x implies y g[i(- y)].push_back(i(x)); // not y implies x } vector<int> component = strongly_connected_components::decompose(g).second; vector<bool> valuation(n); repeat_from (x,1,n+1) { if (component[i(x)] == component[i(- x)]) { // x iff not x return vector<bool>(); // unsat } valuation[x-1] = component[i(x)] > component[i(- x)]; // use components which indices are large } return valuation; } int main() { int n; cin >> n; vector<string> s(n); repeat (i,n) cin >> s[i]; assert (1 <= n and n <= 100000); repeat (i,n) { assert (s[i].length() == 3); for (char c : s[i]) assert ('A' <= c and c <= 'Z' or 'a' <= c and c <= 'z'); } vector<bool> result; if (n <= 52) { // x_i : U_i = S + TT // not x_i : U_i = SS + T vector<pair<int, int> > cnf; map<string, vector<int> > used; repeat (i,n) { int x = i + 1; used[s[i].substr(0, 1)].push_back(+ x); used[s[i].substr(1, 2)].push_back(+ x); used[s[i].substr(0, 2)].push_back(- x); used[s[i].substr(2, 1)].push_back(- x); } for (auto it : used) { for (int x : it.second) for (int y : it.second) if (x < y) { // cerr << "not " << x << " or " << "not " << y << endl; cnf.emplace_back(- x, - y); // not x or not y } } result = twosat(n, cnf); } if (result.empty()) { cout << "Impossible" << endl; } else { repeat (i,n) { if (result[i]) { cout << s[i][0] << ' ' << s[i][1] << s[i][2] << endl; } else { cout << s[i][0] << s[i][1] << ' ' << s[i][2] << endl; } } } return 0; }