結果
| 問題 |
No.2948 move move rotti
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2024-10-25 22:01:18 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 248 ms / 4,000 ms |
| コード長 | 1,930 bytes |
| コンパイル時間 | 1,101 ms |
| コンパイル使用メモリ | 98,124 KB |
| 実行使用メモリ | 40,320 KB |
| 最終ジャッジ日時 | 2024-10-25 22:02:27 |
| 合計ジャッジ時間 | 4,661 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 28 |
ソースコード
#include <iostream>
#include <vector>
#include <bit>
using namespace std;
int main () {
int N, M, K; cin >> N >> M >> K;
vector<int> X(K);
for (int i = 0; i < K; i++) cin >> X[i], X[i]--;
vector<vector<bool>> g(N, vector<bool>(N));
for (int i = 0; i < M; i++) {
int U, V; cin >> U >> V;
U--, V--;
g[U][V] = g[V][U] = true;
}
// dp[i][S][j] := 人iが公園の巡回状況Sで最後に公園jにいる を達成できるか?
vector<vector<vector<bool>>> dp(K, vector<vector<bool>>(1 << N, vector<bool>(N, false)));
for (int i = 0; i < K; i++) {
dp[i][1 << X[i]][X[i]] = true;
}
for (int i = 0; i < K; i++) {
for (int S = 0; S < (1 << N); S++) {
for (int k = 0; k < N; k++) {
if (!dp[i][S][k]) continue;
// 次行く先
for (int nex = 0; nex < N; nex++) {
if (0 < (S & (1 << nex))) continue;
if (!g[k][nex]) continue;
dp[i][S | (1 << nex)][nex] = true;
}
}
}
}
// possible[i][j][k] := 人iがj回の移動で公園kに集まれるか
vector<vector<vector<bool>>> possible(K, vector<vector<bool>>(N, vector<bool>(N, false)));
for (int i = 0; i < K; i++) {
for (int S = 0; S < (1 << N); S++) {
for (int k = 0; k < N; k++) {
if (dp[i][S][k]) possible[i][popcount(static_cast<unsigned int>(S)) - 1][k] = true;
}
}
}
// 判定
bool ok = false;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
bool all = true;
for (int k = 0; k < K; k++) {
if (!possible[k][i][j]) all = false;
}
if (all) ok = true;
}
}
if (ok) {
cout << "Yes" << "\n";
}
else {
cout << "No" << "\n";
}
}