結果
| 問題 |
No.1324 Approximate the Matrix
|
| コンテスト | |
| ユーザー |
👑 |
| 提出日時 | 2020-12-21 23:21:18 |
| 言語 | C (gcc 13.3.0) |
| 結果 |
AC
|
| 実行時間 | 61 ms / 2,000 ms |
| コード長 | 2,884 bytes |
| コンパイル時間 | 622 ms |
| コンパイル使用メモリ | 34,048 KB |
| 実行使用メモリ | 5,376 KB |
| 最終ジャッジ日時 | 2024-09-21 13:16:43 |
| 合計ジャッジ時間 | 2,629 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 42 |
ソースコード
#include <stdio.h>
typedef struct {
int key, id;
} data;
typedef struct {
data obj[40001];
int size;
} min_heap;
void push(data x, min_heap* h)
{
int i = ++(h->size), j = i >> 1;
data tmp;
h->obj[i] = x;
while (j > 0) {
if (h->obj[i].key < h->obj[j].key) {
tmp = h->obj[j];
h->obj[j] = h->obj[i];
h->obj[i] = tmp;
i = j;
j >>= 1;
} else break;
}
}
data pop(min_heap* h)
{
int i = 1, j = 2;
data output = h->obj[1], tmp;
h->obj[1] = h->obj[(h->size)--];
while (j <= h->size) {
if (j < h->size && h->obj[j^1].key < h->obj[j].key) j ^= 1;
if (h->obj[j].key < h->obj[i].key) {
tmp = h->obj[j];
h->obj[j] = h->obj[i];
h->obj[i] = tmp;
i = j;
j <<= 1;
} else break;
}
return output;
}
void chmin(int* a, int b)
{
if (*a > b) *a = b;
}
int main()
{
int i, j, N, K, A[201], B[201], P[201][201];
scanf("%d %d", &N, &K);
for (i = 1; i <= N; i++) scanf("%d", &(A[i]));
for (i = 1; i <= N; i++) scanf("%d", &(B[i]));
for (i = 1; i <= N; i++) for (j = 1; j <= N; j++) scanf("%d", &(P[i][j]));
const int sup = 1 << 30;
int flow[403][403] = {}, cap[403][403] = {}, cost[403][403], pi[403], s = N * 2 + 1, t = N * 2 + 2;
for (i = 1; i <= N; i++) {
cap[s][i] = A[i];
cost[s][i] = 0;
cap[i+N][t] = B[i];
cost[i+N][t] = 0;
}
for (i = 1; i <= N; i++) {
for (j = 1; j <= N; j++) {
cap[i][j+N] = K;
cost[i][j+N] = 1 - P[i][j] * 2;
}
}
int u, w, n = N * 2 + 2;
for (i = 1; i <= n; i++) pi[i] = sup;
for (i = 0, pi[s] = 0; i < 4; i++) {
for (u = 1; u <= n; u++) {
if (pi[u] == sup) continue;
for (w = 1; w <= n; w++) if (cap[u][w] > 0) chmin(&(pi[w]), pi[u] + cost[u][w]);
}
}
int k, dist[403], prev[403], flag[403];
min_heap h;
data d;
for (k = 1; k <= K; k++) {
h.size = 0;
d.key = 0;
d.id = s;
push(d, &h);
for (u = 1; u <= n; u++) {
dist[u] = sup;
prev[u] = -1;
flag[u] = 0;
}
dist[s] = 0;
prev[s] = s;
while (h.size > 0) {
d = pop(&h);
u = d.id;
if (flag[u] == 1) continue;
else flag[u] = 1;
for (w = 1; w <= n; w++) {
if (flow[u][w] < cap[u][w] && dist[w] > dist[u] + cost[u][w] - pi[w] + pi[u]) {
dist[w] = dist[u] + cost[u][w] - pi[w] + pi[u];
prev[w] = u;
d.key = dist[w];
d.id = w;
push(d, &h);
}
}
}
for (w = t, u = prev[w]; w != s; w = u, u = prev[w]) {
if (flow[w][u] > 0) {
flow[w][u]--;
cost[w][u] -= 2;
cost[u][w] += 2;
if (flow[w][u] == 0) cap[u][w] = 0;
} else {
flow[u][w]++;
if (u <= N * 2 && w <= N * 2) {
cost[u][w] += 2;
cost[w][u] = 2 - cost[u][w];
cap[w][u] = 1;
}
}
}
for (u = 1; u <= n; u++) if (dist[u] != sup) pi[u] += dist[u];
}
long long ans = 0;
for (i = 1; i <= N; i++) for (j = 1; j <= N; j++) ans += (P[i][j] - flow[i][j+N]) * (P[i][j] - flow[i][j+N]);
printf("%lld\n", ans);
fflush(stdout);
return 0;
}