結果
問題 | No.274 The Wall |
ユーザー | moti |
提出日時 | 2015-09-12 02:02:23 |
言語 | C++11 (gcc 11.4.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 3,313 bytes |
コンパイル時間 | 760 ms |
コンパイル使用メモリ | 95,252 KB |
実行使用メモリ | 61,824 KB |
最終ジャッジ日時 | 2024-07-19 05:42:01 |
合計ジャッジ時間 | 2,501 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
5,248 KB |
testcase_01 | WA | - |
testcase_02 | WA | - |
testcase_03 | WA | - |
testcase_04 | WA | - |
testcase_05 | AC | 2 ms
5,376 KB |
testcase_06 | WA | - |
testcase_07 | AC | 1 ms
5,376 KB |
testcase_08 | AC | 1 ms
5,376 KB |
testcase_09 | WA | - |
testcase_10 | AC | 2 ms
5,376 KB |
testcase_11 | WA | - |
testcase_12 | AC | 26 ms
5,376 KB |
testcase_13 | AC | 2 ms
5,376 KB |
testcase_14 | AC | 7 ms
5,376 KB |
testcase_15 | AC | 17 ms
5,376 KB |
testcase_16 | AC | 152 ms
61,824 KB |
testcase_17 | AC | 138 ms
55,424 KB |
testcase_18 | AC | 137 ms
57,600 KB |
testcase_19 | AC | 30 ms
5,376 KB |
testcase_20 | AC | 35 ms
5,376 KB |
testcase_21 | AC | 37 ms
5,376 KB |
testcase_22 | WA | - |
testcase_23 | WA | - |
testcase_24 | AC | 39 ms
5,376 KB |
testcase_25 | AC | 39 ms
5,376 KB |
ソースコード
#include <iostream> #include <algorithm> #include <cmath> #include <vector> #include <complex> #include <queue> #include <deque> #include <set> #include <map> #include <unordered_set> #include <unordered_map> #include <iomanip> #include <cstring> #include <assert.h> #include <array> #include <cstdio> using namespace std; #define REP(i,a,b) for(int i=a;i<(int)b;i++) #define rep(i,n) REP(i,0,n) typedef long long ll; template<typename T> T read(std::istream& is) { T value; is >> value; return value; } template<typename... Ts> std::istream& operator>>(std::istream& is , std::tuple<Ts...>& tuple) { tuple = std::make_tuple( read<Ts>(is)... ); return is; } const int MAX_V = 5000; vector<int> G[MAX_V]; vector<int> rG[MAX_V]; vector<int> vs; bool used[MAX_V]; int cmp[MAX_V]; void add_edge(int from, int to) { G[from].push_back(to); rG[to].push_back(from); } void dfs(int v) { used[v] = true; for(int i=0; i<G[v].size(); i++) { if(!used[G[v][i]]) dfs(G[v][i]); } vs.push_back(v); } void rdfs(int v, int k) { used[v] = true; cmp[v] = k; for(int i=0; i<rG[v].size(); i++) { if(!used[rG[v][i]]) rdfs(rG[v][i], k); } } int scc() { memset(used, 0, sizeof(used)); vs.clear(); for(int v=0; v<MAX_V; v++) { if(!used[v]) dfs(v); } memset(used, 0, sizeof(used)); // 逆辺にしたらDAGなら進めないところが、巡回路であれば進めるので、それらを同じ数字でマークできる。 int k = 0; for(int i=(int)vs.size()-1; i>=0; i--) { if(!used[vs[i]]) rdfs(vs[i], k++); } return k; } const int MAX_N = 2001; int N, M; using tpl = tuple<int, int>; tpl lr[MAX_N * 2]; bool uncover(tpl a, tpl b) { auto&& al = get<0>(a), &&ar = get<1>(a); auto&& bl = get<0>(b), &&br = get<1>(b); return !( (bl <= al && al <= br) || (bl <= ar && ar <= br) || (al <= bl && bl <= ar) || (al <= br && br <= ar) ); } int main() { cin >> N >> M; rep(i, N) { cin >> lr[i]; lr[N+i] = make_tuple(M-1-get<1>(lr[i]), M-1-get<0>(lr[i])); //printf("(%d, %d) -> (%d, %d)\n", get<0>(lr[i]), get<1>(lr[i]), get<0>(lr[N+i]), get<1>(lr[N+i])); } /* rep(i, N) REP(j, i+1, N) { if(cover(lr[i], lr[j])) { add_edge(i, j); } if(cover(lr[i], lr[N+j])) { add_edge(i, N+j); } if(cover(lr[N+i], lr[j])) { add_edge(N+i, j); } if(cover(lr[N+i], lr[N+j])) { add_edge(N+i, N+j); } } */ /* 基本形: p -> q <=> ~q -> ~p <=> ~p v q <=> ~(p ∧ ~q) p, q の符号の組み合わせをすべて試す */ rep(i, N) REP(j, i+1, N) { // p -> ~q <=> q -> ~p <=> ~p v ~q <=> ~(p ∧ q) if(!uncover(lr[i], lr[j])) { add_edge(j, N+i); add_edge(i, N+j); } // ~p -> ~q <=> q -> p <=> p v ~q <=> ~(~p ∧ q) if(!uncover(lr[N+i], lr[j])) { add_edge(N+i, N+j); add_edge(j, i); } // p -> q <=> ~q -> ~p <=> ~p v q <=> ~(p ∧ ~q) if(!uncover(lr[i], lr[N+j])) { add_edge(i, j); add_edge(N+j, N+i); } // ~p -> q <=> ~q -> p <=> p v q <=> ~(~p ∧ ~q) if(!uncover(lr[N+i], lr[N+j])) { add_edge(N+i, j); add_edge(N+j, i); } } scc(); rep(i, N) { if(cmp[i] == cmp[N+i]) { cout << "NO\n"; return 0; } } cout << "YES\n"; return 0; }