题意
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]
val<l[i]。
k
<
<
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<r[i]+1。
这样连接点
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
2 − S A T 2-SAT 2−SAT中一条关系表达式一定能退出两条有向边,不能漏边了!!!
#include <bits/stdc++.h>
using namespace std;
vector<vector<int>> e;
vector<int> l, r;
vector<bool> vis;
stack<int> stk;
vector<int> 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<int>());
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<int> 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;
}