QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#874996 | #9345. Artful Paintings | SkyWave | WA | 99ms | 3840kb | C++14 | 3.1kb | 2025-01-28 23:27:47 | 2025-01-28 23:27:48 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
void solve() {
constexpr int N = 3000, M = 3000;
static int edge[M + M + 1 + N + N + 1 + 1][3], tail[N + 1];
int n, m1, m2;
cin >> n >> m1 >> m2;
memset(tail, 0, sizeof(int) * (n + 1));
int m = 0;
auto addEdge = [&](int u, int v, int w) {
edge[++m][0] = v;
edge[m][1] = w;
edge[m][2] = tail[u];
tail[u] = m;
};
for (int i = 1; i <= m1; ++i) {
int l, r, k;
cin >> l >> r >> k;
addEdge(r, l - 1, -k); // S[r] - S[l-1] >= k → S[l-1] <= S[r] - k
}
for (int i = 1; i <= m2; ++i) {
int l, r, k;
cin >> l >> r >> k;
addEdge(l - 1, r, -k); // 初始权值为 -k,后续调整时加上 mid
}
for (int i = 1; i <= n; ++i) {
addEdge(i, i - 1, 0); // S[i] >= S[i-1]
addEdge(i - 1, i, 1); // S[i] <= S[i-1] + 1
}
auto check = [&](int mid) {
// 调整类型2约束的权值:边权变为 -k + mid
for (int i = m1 + 1; i <= m1 + m2; ++i) {
edge[i][1] += mid;
}
int old_m = m;
// 添加两条边强制 S[n] = mid
addEdge(0, n, mid); // S[n] <= mid
addEdge(n, 0, -mid); // S[n] >= mid
queue<int> que;
que.push(0);
static bitset<N + 1> inq;
inq.reset();
inq[0] = true;
static int dis[N + 1];
memset(dis + 1, 0x3f, sizeof(int) * n);
dis[0] = 0;
static int cnt[N + 1];
memset(cnt, 0, sizeof(int) * (n + 1));
bool res = true;
while (!que.empty() && res) {
int u = que.front(); que.pop();
inq[u] = false;
for (int i = tail[u]; i; i = edge[i][2]) {
int v = edge[i][0], w = edge[i][1];
if (dis[u] + w < dis[v]) {
dis[v] = dis[u] + w;
if (!inq[v]) {
if (++cnt[v] > n) { // 包含n+1个节点,有负环
res = false;
break;
}
que.push(v);
inq[v] = true;
}
}
}
}
// 恢复边的状态
m = old_m;
for (int i = m1 + 1; i <= m1 + m2; ++i) {
edge[i][1] -= mid;
}
// 恢复 tail 数组,因为添加的临时边被撤销
tail[0] = edge[m][2]; // 恢复原来的最后一条边
tail[n] = edge[m-1][2]; // 假设 n 的边在添加时没有其他操作
return res;
};
int l = 0, r = n;
while (l <= r) {
int mid = (l + r) >> 1;
if (check(mid)) {
r = mid - 1;
} else {
l = mid + 1;
}
}
cout << l << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 3584kb
input:
1 3 1 1 1 2 1 2 2 1
output:
1
result:
ok single line: '1'
Test #2:
score: -100
Wrong Answer
time: 99ms
memory: 3840kb
input:
1 1000 500 500 479 860 170 73 939 25 363 772 30 185 584 89 326 482 10 784 949 23 384 740 114 233 693 45 167 724 211 217 436 95 46 701 153 138 585 67 321 388 11 114 890 194 407 854 74 438 845 117 9 718 259 393 576 35 182 707 257 451 766 136 150 382 31 468 785 40 202 490 46 326 815 59 272 441 77 123 8...
output:
500
result:
wrong answer 1st lines differ - expected: '492', found: '500'