結果
問題 |
No.95 Alice and Graph
|
ユーザー |
|
提出日時 | 2025-08-20 19:58:37 |
言語 | D (dmd 2.109.1) |
結果 |
AC
|
実行時間 | 2,251 ms / 5,000 ms |
コード長 | 1,581 bytes |
コンパイル時間 | 4,708 ms |
コンパイル使用メモリ | 196,160 KB |
実行使用メモリ | 13,312 KB |
最終ジャッジ日時 | 2025-08-20 19:58:51 |
合計ジャッジ時間 | 10,728 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 14 |
ソースコード
module main; // https://kmjp.hatenablog.jp/entry/2014/12/08/1100 より // ビットDP import std; // aとbを比較してbの方が小さいならばaの値をbに更新する void chMin(T)(ref T a, in T b) { if (a > b) a = b; } // 多次元配列をある値で埋める void fill(A, T)(ref A a, T value) if (isArray!A) { alias E = ElementType!A; static if (isArray!E) { foreach (ref e; a) fill(e, value); } else { a[] = value; } } void main() { // 入力 int N, M, K; readln.chomp.formattedRead("%d %d %d", N, M, K); auto G = new int[][](N, N); fill(G, 1000); foreach (i; 0 .. N) G[i][i] = 0; foreach (_; 0 .. M) { int u, v; readln.chomp.formattedRead("%d %d", u, v); --u, --v; G[u][v] = G[v][u] = 1; } // 答えの計算 // ワーシャル・フロイド法 foreach (i; 0 .. N) foreach (x; 0 .. N) foreach (y; 0 .. N) chMin(G[x][y], G[x][i] + G[i][y]); long ans = 0; int[] V = [0]; auto dp = new int[][](1 << (K + 1), K + 1); immutable INF = 10 ^^ 9; foreach_reverse (i; 1 .. N) { if (V.length >= K + 1) break; V ~= i; fill(dp, INF); dp[1][0] = 0; foreach (mask; 1 .. 1 << V.length) { foreach (x; 0 .. V.length) { if (mask & (1 << x)) { foreach (y; 0 .. V.length) { if (x != y && (mask & (1 << y))) chMin(dp[mask][x], dp[mask ^ (1 << x)][y] + G[V[x]][V[y]]); } } } } bool ok = false; foreach (j; 0 .. V.length) if (dp[(1 << V.length) - 1][j] <= K) { ok = true; break; } if (!ok) V.popBack; else ans += (1L << i) - 1; } // 答えの出力 writeln(ans); }