Codeforces Round #585 (Div. 2) F. Radio Stations

题意 2 ? S A T 2-SAT 2?SAT多了一个边的范围,其实只需要把点的范围加上去就行了即:
第 i i i个点 ( l [ i ] , r [ i ] ) (l[i], r[i]) (l[i],r[i]),那么构造点 j j j, k k k对应 l [ i ] l[i] l[i], r [ i ] + 1 r[i]+1 r[i]+1。
j < < 1 j<<1 j<<1, j < < 1 ∣ 1 j<<1|1 j<<1∣1分别对应 v a l > = l [ i ] val >= l[i] val>=l[i]与 v a l < l [ i ] val < l[i] valk < < 1 k<<1 k<<1, k < < 1 ∣ 1 k<<1|1 k<<1∣1分别对应 v a l > = r [ i ] + 1 val >= r[i]+1 val>=r[i]+1与 v a l < r [ i ] + 1 val < r[i]+1 val 这样连接点 i < < 1 → j < < 1 i<<1 \to j<<1 i<<1→j<<1, i < < 1 → k < < 1 ∣ 1 i<<1 \to k<<1|1 i<<1→k<<1∣1,以及 j < < 1 ∣ 1 → i < < 1 ∣ 1 j<<1|1 \to i<<1|1 j<<1∣1→i<<1∣1, k < < 1 → i < < 1 ∣ 1 k<<1 \to i<<1|1 k<<1→i<<1∣1。
然后把 0 ∽ M + 1 0 \backsim M+1 0∽M+1 的点按逻辑连接起来就行了。
小trick 【Codeforces Round #585 (Div. 2) F. Radio Stations】 2 ? S A T 2-SAT 2?SAT中一条关系表达式一定能退出两条有向边,不能漏边了!!!

#include using namespace std; vector> e; vector l, r; vector vis; stack stk; vector dfn, low, be; int tot = 0, cnt = 0; void tarjan(int u) { dfn[u] = low[u] = ++tot; stk.push(u); vis[u] = true; for (auto &v : e[u]) { if (!dfn[v]) { tarjan(v); low[u] = min(low[u], low[v]); } else if (vis[v]) { low[u] = min(low[u], dfn[v]); } } if (dfn[u] == low[u]) { ++cnt; // cout << "stk: "; while (stk.top() != u) { int v = stk.top(); stk.pop(); // cout << v << " "; be[v] = cnt; vis[v] = false; } // cout << u << endl; stk.pop(); be[u] = cnt; vis[u] = false; } }int main() { int n, p, M, m; cin >> n >> p >> M >> m; const int maxn = (p + M + 1) * 2 + 10; e.assign(maxn, vector()); l.assign(p, 0); r.assign(p, 0); int x, y; for (int i = 0; i < n; ++i) { cin >> x >> y; --x; --y; e[x<<1|1].emplace_back(y<<1); e[y<<1|1].emplace_back(x<<1); } for (int i = 0; i < p; ++i) { cin >> l[i] >> r[i]; e[i<<1].emplace_back((l[i] + p)<<1); e[i<<1].emplace_back((r[i] + p + 1)<<1|1); e[(l[i] + p)<<1|1].emplace_back(i<<1|1); e[(r[i] + p + 1)<<1].emplace_back(i<<1|1); } for (int i = 0; i < m; ++i) { cin >> x >> y; --x; --y; e[x<<1].emplace_back(y<<1|1); e[y<<1].emplace_back(x<<1|1); } for (int i = 0; i <= M; ++i) { e[(i + p + 1)<<1].emplace_back((i + p)<<1); e[(i + p)<<1|1].emplace_back((i + p + 1)<<1|1); } vis.assign(maxn, false); dfn.assign(maxn, 0); low.assign(maxn, 0); be.assign(maxn, 0); for (int i = 0, _i = 2 * (p + M + 1); i <= _i; ++i) if (!dfn[i]) tarjan(i); for (int i = 0, _i = p + M + 1; i <= _i; ++i) { if (be[i<<1] == be[i<<1|1]) { cout << -1 << endl; return 0; } } vector ans; int val = 0; for (int i = 0; i < p; ++i) { // cout << "i: " << be[i<<1] << " " << be[i<<1|1] << endl; if (be[i<<1] < be[i<<1|1]) { ans.emplace_back(i); val = max(val, l[i]); } } cout << ans.size() << " " << val << "\n"; for (int i = 0, _i = ans.size(); i < _i; ++i) { if (i) cout << " "; cout << ans[i] + 1; } cout << endl; return 0; }

    推荐阅读