結果

問題 No.274 The Wall
ユーザー tsutaj
提出日時 2019-07-09 23:21:10
言語 C++14
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 809 ms / 2,000 ms
コード長 6,443 bytes
コンパイル時間 1,172 ms
コンパイル使用メモリ 95,108 KB
実行使用メモリ 324,864 KB
最終ジャッジ日時 2024-06-22 02:29:01
合計ジャッジ時間 4,091 ms
ジャッジサーバーID
(参考情報)
judge5 / judge2
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 4
other AC * 22
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

#include <vector>
#include <iostream>
#include <cstdio>
#include <utility>
#include <tuple>
#include <algorithm>
using namespace std;
//
template <typename T = int>
struct Edge {
int from, to;
T cost;
Edge(int s, T d = 1) : to(s), cost(d) {}
Edge(int f, int s, T d) : from(f), to(s), cost(d) {}
bool operator<(const Edge &e) const {
return cost < e.cost;
}
bool operator>(const Edge &e) const {
return cost > e.cost;
}
};
template <typename T = int>
using Graph = vector< vector< Edge<T> > >;
//
// Verified: AOJ GRL_3_C (Strongly Connected Components)
// Verified: ARC030 C () ←
// 2 DFS
// DFS
//
// DFS
// DAG
//
template <typename T = int>
struct GraphSCC {
public:
const int n;
vector<bool> isthrough;
vector<int> vs, cmp;
vector< vector<int> > G, rG, H; //
GraphSCC(vector< vector< Edge<T> > > &g) :
n(g.size()), isthrough(n, false), cmp(n, 0), G(n), rG(n) {
for(int i=0; i<n; i++) {
for(size_t j=0; j<g[i].size(); j++) {
G[i].push_back(g[i][j].to);
rG[ g[i][j].to ].push_back(i);
}
}
}
void SCC_dfsone(int cur) {
isthrough[cur] = true;
for(size_t i=0; i<G[cur].size(); i++) {
if(!isthrough[G[cur][i]]) {
SCC_dfsone(G[cur][i]);
}
}
vs.push_back(cur);
}
void SCC_dfstwo(vector<int> &vec, int cur, int k) {
cmp[cur] = k;
isthrough[cur] = true;
vec.push_back(cur);
for(size_t i=0; i<rG[cur].size(); i++) {
if(!isthrough[rG[cur][i]]) {
SCC_dfstwo(vec, rG[cur][i], k);
}
}
}
//
pair<vector<int>, int> scc() {
// 1DFS
for(int i=0; i<n; i++)
if(!isthrough[i]) SCC_dfsone(i);
fill(isthrough.begin(), isthrough.end(), false);
reverse(vs.begin(), vs.end());
int k = 0; vector< vector<int> > S;
// 2DFS
for(size_t i=0; i<vs.size(); i++) {
if(!isthrough[vs[i]]) {
S.push_back(vector<int>());
SCC_dfstwo(S.back(), vs[i], k++);
}
}
H.resize(k);
fill(isthrough.begin(), isthrough.end(), false);
for(size_t i=0; i<k; i++) {
for(size_t j=0; j<S[i].size(); j++) {
int v = S[i][j];
for(size_t x=0; x<G[v].size(); x++) {
int u = G[v][x];
if(isthrough[cmp[u]] || cmp[v] == cmp[u]) continue;
isthrough[cmp[u]] = true;
H[cmp[v]].push_back(cmp[u]);
}
}
for(size_t j=0; j<H[i].size(); j++) isthrough[ H[i][j] ] = false;
}
return make_pair(cmp, k);
}
};
// 2 (2-SAT)
// : SCC (graph_010_scc.cpp)
struct TwoSAT {
int N; Graph<> G;
TwoSAT(int N_) : N(N_), G(2*N_) {}
int neg(int k) { return (k+N) % (2*N); }
void add_edge(int u, int v) {
G[u].emplace_back(v);
}
void add_AorB(int a, int b) {
// (a or b) -> (na => b) and (nb => a)
add_edge(neg(a), b);
add_edge(neg(b), a);
}
void add_NAorB(int a, int b) {
// (na or b) -> (a => b) and (nb => na)
add_edge(a, b);
add_edge(neg(b), neg(a));
}
void add_AorNB(int a, int b) {
// (a or nb) -> (na => nb) and (b => a)
add_edge(neg(a), neg(b));
add_edge(b, a);
}
void add_NAorNB(int a, int b) {
// (na or nb) -> (a => nb) and (b => na)
add_edge(a, neg(b));
add_edge(b, neg(a));
}
vector<int> build() {
GraphSCC<> scc(G);
vector<int> group, res(N); int K;
tie(group, K) = scc.scc();
for(int i=0; i<N; i++) {
if(group[i] == group[N+i]) return {};
res[i] = (group[i] > group[N+i]);
}
return res;
}
};
void yuki_274() {
int N, M; scanf("%d%d", &N, &M);
vector<int> L(N), R(N);
auto flip = [&](int l, int r) {
return make_pair(M - 1 - r, M - 1 - l);
};
auto intersect = [&](int al, int ar, int bl, int br) {
return !(ar < bl or br < al);
};
for(int i=0; i<N; i++) {
scanf("%d%d", &L[i], &R[i]);
}
TwoSAT tsat(N);
for(int i=0; i<N; i++) {
for(int j=i+1; j<N; j++) {
for(int bit=0; bit<4; bit++) {
int al = L[i], ar = R[i];
int bl = L[j], br = R[j];
if(bit & 1) tie(al, ar) = flip(al, ar);
if(bit & 2) tie(bl, br) = flip(bl, br);
if(intersect(al, ar, bl, br)) {
switch(bit) {
case 0:
// A and B -> NA or NB
tsat.add_NAorNB(i, j);
break;
case 1:
// NA and B -> A or NB
tsat.add_AorNB(i, j);
break;
case 2:
// A and NB -> NA or B
tsat.add_NAorB(i, j);
break;
case 3:
// NA and NB -> A or B
tsat.add_AorB(i, j);
break;
}
}
}
}
}
auto res = tsat.build();
if(res.size() == N) puts("YES");
else puts("NO");
}
int main() {
yuki_274();
return 0;
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0