結果
| 問題 | No.3699 引き抜き交渉 |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2026-08-27 23:11:56 |
| 言語 | JavaScript (node v26.7.0 + ACL) |
| 結果 |
AC
不安定
|
| 実行時間 | 61 ms / 2,000 ms |
| + 746µs | |
| コード長 | 2,427 bytes |
| 記録 | |
| コンパイル時間 | 3 ms |
| コンパイル使用メモリ | 6,400 KB |
| 実行使用メモリ | 63,820 KB |
| 最終ジャッジ日時 | 2026-09-09 20:50:55 |
| 合計ジャッジ時間 | 2,098 ms |
|
ジャッジサーバーID (参考情報) |
judge3_0 / judge1_1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 15 |
ソースコード
// プロジェクト選択問題(最小カット)。
// 総取り Σ(a_i + b_i) から「諦める分」を引く。諦める分の最小 = 最小カット。
// S→i に a_i (i を乙にすると a_i を失う)
// i→T に b_i (i を甲にすると b_i を失う)
// i↔j に c_j (別チームになると c_j を失う。両向き c_j)
// 答え = Σ(a_i + b_i) - mincut
function maxflow(n, edges, s, t) {
// Dinic。edges は [from, to, cap] の配列(逆辺は自動で張る)
const head = new Int32Array(n).fill(-1);
const nxt = [], to = [], cap = [];
const addEdge = (u, v, c, rc) => {
to.push(v); cap.push(c); nxt.push(head[u]); head[u] = to.length - 1;
to.push(u); cap.push(rc); nxt.push(head[v]); head[v] = to.length - 1;
};
for (const [u, v, c, rc] of edges) addEdge(u, v, c, rc ?? 0);
const level = new Int32Array(n);
const iter = new Int32Array(n);
const queue = new Int32Array(n);
const bfs = () => {
level.fill(-1);
let qh = 0, qt = 0;
level[s] = 0; queue[qt++] = s;
while (qh < qt) {
const v = queue[qh++];
for (let e = head[v]; e !== -1; e = nxt[e]) {
if (cap[e] > 0 && level[to[e]] < 0) { level[to[e]] = level[v] + 1; queue[qt++] = to[e]; }
}
}
return level[t] >= 0;
};
const dfs = (v, f) => {
if (v === t) return f;
for (; iter[v] !== -1; iter[v] = nxt[iter[v]]) {
const e = iter[v], u = to[e];
if (cap[e] > 0 && level[v] < level[u]) {
const d = dfs(u, Math.min(f, cap[e]));
if (d > 0) { cap[e] -= d; cap[e ^ 1] += d; return d; }
}
}
return 0;
};
let flow = 0;
while (bfs()) {
for (let i = 0; i < n; i++) iter[i] = head[i];
let f;
while ((f = dfs(s, Infinity)) > 0) flow += f;
}
return flow;
}
function solveF(input) {
const d = input.split(/\s+/).filter(s => s.length);
let p = 0;
const n = +d[p++], m = +d[p++];
const S = n, T = n + 1;
const edges = [];
let total = 0;
for (let i = 0; i < n; i++) {
const a = +d[p++], b = +d[p++];
total += a + b;
edges.push([S, i, a]);
edges.push([i, T, b]);
}
for (let j = 0; j < m; j++) {
const u = +d[p++] - 1, v = +d[p++] - 1, c = +d[p++];
// 無向辺は「両方向に容量 c」で表す(逆辺も c)
edges.push([u, v, c, c]);
}
return String(total - maxflow(n + 2, edges, S, T));
};
console.log(solveF(require("fs").readFileSync(0, "utf8")));