QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#176043 | #7185. Poor Students | ucup-team1883 | TL | 1ms | 3308kb | C++14 | 4.1kb | 2023-09-11 08:46:28 | 2023-09-11 08:46:29 |
Judging History
answer
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <numeric>
#include <vector>
#include <cassert>
#include <queue>
using namespace std;
using ll = long long;
using ull = unsigned long long;
#define LOG(f...) fprintf(stderr, f)
// #define DBG(f...) printf("%3d: ", __LINE__), printf(f)
#define DBG(f...) void()
#define all(cont) begin(cont), end(cont)
#ifdef __linux__
#define getchar getchar_unlocked
#define putchar putchar_unlocked
#endif
template <class T> void read(T &x) {
char ch; x = 0;
int f = 1;
while (isspace(ch = getchar()));
if (ch == '-') ch = getchar(), f = -1;
do x = x * 10 + (ch - '0'); while (isdigit(ch = getchar()));
x *= f;
}
template <class T, class ...A> void read(T &x, A&... args) { read(x); read(args...); }
struct vid {
ll v;
int id;
bool operator<(vid rhs) const { return v == rhs.v ? id > rhs.id : v > rhs.v; }
bool operator==(vid rhs) const { return v == rhs.v && id == rhs.id; }
};
using min_heap = priority_queue<vid>;
const int N = 50005;
const int MAXK = 10;
const ll LLINF = 0x3f3f3f3f3f3f3f3f;
struct del_heap {
min_heap H, D;
void push(vid x) { H.push(x); }
void pop(vid x) { D.push(x); }
vid top() {
while (!D.empty() && H.top() == D.top()) H.pop(), D.pop();
return H.top();
}
bool empty() { return H.size() == D.size(); }
};
int n, m;
int cost[N][MAXK], cap[MAXK];
vid trans[MAXK][MAXK];
del_heap H[MAXK][MAXK], direct[MAXK];
ll dist[MAXK];
int src[MAXK], interm[MAXK];
int mat[N];
void initalize() {
for (int j = 0; j < m; ++j) {
vector<vid> seq(n);
for (int i = 0; i < n; ++i)
seq[i] = {cost[i][j], i};
direct[j] = {min_heap(all(seq)), min_heap{}};
}
}
void attach(int u, int v, bool no_direct = false) {
DBG("attach %d %d\n", u, v);
mat[u] = v;
--cap[v];
if (!no_direct)
for (int i = 0; i < n; ++i)
direct[i].pop({cost[u][i], u});
for (int i = 0; i < n; ++i)
if (i != v)
H[v][i].push({cost[u][i] - cost[u][v], u});
}
void detach(int u, int v, bool no_direct = false) {
DBG("detach %d %d\n", u, v);
++cap[v];
if (!no_direct)
for (int i = 0; i < n; ++i)
direct[i].push({cost[u][i], u});
for (int i = 0; i < n; ++i)
if (i != v)
H[v][i].pop({cost[u][i] - cost[u][v], u});
}
void augment() {
for (int i = 0; i < m; ++i)
if (direct[i].empty()) dist[i] = LLINF;
else dist[i] = direct[i].top().v, src[i] = m + direct[i].top().id;
for (int i = 0; i < m; ++i)
for (int j = 0; j < m; ++j) {
if (i != j)
DBG("trans[%d][%d] = %lld %d\n", i, j, trans[i][j].v, trans[i][j].id);
trans[i][j] = H[i][j].empty() ? vid{LLINF, 0} : H[i][j].top();
}
for (int r = 0; r < m; ++r)
for (int i = 0; i < m; ++i)
for (int j = 0; j < m; ++j)
if (i != j && dist[i] + trans[i][j].v < dist[j]) {
interm[j] = trans[i][j].id;
dist[j] = dist[i] + trans[i][j].v;
src[j] = i;
}
int u = -1;
for (int i = 0; i < m; ++i) {
if (cap[i] == 0) continue;
if (u == -1 || dist[i] < dist[u]) u = i;
}
assert(u != -1);
DBG("path ends at %d : dist %lld\n", u, dist[u]);
while (true) {
if (src[u] >= m) {
DBG("path starts at %d\n", src[u] - m);
attach(src[u] - m, u);
break;
}
else {
DBG("%d -> %d -> %d\n", src[u], interm[u], u);
detach(interm[u], mat[u]);
attach(interm[u], u);
u = src[u];
}
}
}
int main() {
#ifdef LOCAL
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
read(n, m);
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
read(cost[i][j]);
for (int i = 0; i < m; ++i)
read(cap[i]);
initalize();
memset(mat, -1, sizeof(mat));
for (int i = 0; i < n; ++i)
augment();
ll ans = 0;
for (int i = 0; i < n; ++i)
DBG("%d -> %d\n", i, mat[i]);
for (int i = 0; i < n; ++i) {
assert(mat[i] != -1);
ans += cost[i][mat[i]];
}
printf("%lld\n", ans);
return 0;
}
詳細信息
Test #1:
score: 100
Accepted
time: 1ms
memory: 3308kb
input:
6 2 1 2 1 3 1 4 1 5 1 6 1 7 3 4
output:
12
result:
ok answer is '12'
Test #2:
score: -100
Time Limit Exceeded
input:
3 3 1 2 3 2 4 6 6 5 4 1 1 1