結果
| 問題 | No.114 遠い未来 |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2026-06-30 22:33:59 |
| 言語 | C++23 (gcc 15.2.0 + boost 1.90.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 4,981 bytes |
| 記録 | |
| コンパイル時間 | 5,162 ms |
| コンパイル使用メモリ | 394,276 KB |
| 実行使用メモリ | 19,968 KB |
| 最終ジャッジ日時 | 2026-06-30 22:34:23 |
| 合計ジャッジ時間 | 21,035 ms |
|
ジャッジサーバーID (参考情報) |
judge2_0 / judge1_0 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 15 TLE * 1 -- * 9 |
ソースコード
// ===== ライブラリインクルード =====
#include <bit>
#include <bits/stdc++.h>
#include <queue>
#include <ratio>
using namespace std;
#include <atcoder/all>
using namespace atcoder;
// ===== 型の省略名定義 =====
using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
using i128 = __int128;
using vc = vector<char>;
using vvc = vector<vector<char>>;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using vll = vector<ll>;
using vvll = vector<vector<ll>>;
using vd = vector<double>;
using vvd = vector<vector<double>>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using vpii = vector<pii>;
using vvpii = vector<vector<pii>>;
using vpll = vector<pll>;
using vvpll = vector<vector<pll>>;
using vs = vector<string>;
// ===== 略記用マクロ =====
#define rep(i, n) for (auto i = std::decay_t<decltype(n)>{0}; i < (n); ++i)
#define rrep(i, n) for (auto i = (n); i-- > 0;)
#define nfor(i, l, r) for (auto i = (l); i < (r); ++i)
#define rnfor(i, l, r) for (auto i = (r); i-- > (l); )
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define fi first
#define se second
// ===== 無限大定数 =====
constexpr int INF = 1e9 + 10;
constexpr ll LINF = 4e18 + 10;
constexpr i128 INF128 = 1e37 + 10;
// ===== 入出力 =====
template <class T, class U>
ostream& operator<<(ostream& os, const pair<T, U>& p)
{return os << p.first << " " << p.second;}
template <typename T>
concept HasVal = requires(T v) {{ v.val() } -> convertible_to<long long>;};
ostream& operator<<(ostream& os, HasVal auto v) {return os << v.val();}
template <class T>
void print_vector(const vector<T>& v, const string& sep = "\n", bool omit_last = false)
{
int siz = (int)v.size();
rep(i, siz)
{
cout << v[i];
if(!(omit_last && i == siz - 1)) cout << sep;
}
}
void yes_no(bool ans, bool omit_break = false) {cout << (ans ? "Yes" : "No") << (omit_break ? "" : "\n");}
template<typename T> T nINF(T ans, T inf_val) {return (ans >= inf_val ? -1 : ans);}
int nINF(int ans) {return (ans >= INF ? -1 : ans);}
ll nINF(ll ans) {return (ans >= LINF ? -1 : ans);}
// ===== 汎用関数 =====
template <class T, class U> bool chmax(T &a, U b){ if(a<b){a=b; return true;} return false;}
template <class T, class U> bool chmin(T &a, U b){ if(a>b){a=b; return true;} return false;}
template <class T> void dedup(vector<T>& v) {v.erase(unique(all(v)), v.end());}
// ========== テンプレ終わり ==========
using mint = modint998244353;
using vm = vector<mint>;
using vvm = vector<vm>;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m, t;
cin >> n >> m >> t;
vvpii g(n);
rep(i, m)
{
int a, b, c;
cin >> a >> b >> c;
--a; --b;
g[a].push_back({b, c});
g[b].push_back({a, c});
}
vi v(t);
for(int& x : v) cin >> x, --x;
sort(all(v));
if(t <= 16)
{
vvi dp(1<<t, vi(n, INF));
rep(i, t) dp[1<<i][v[i]] = 0;
vvc determined(1<<t, vc(n, false));
priority_queue<pii, vpii, greater<pii>> pq;
nfor(S, 1, 1<<t)
{
for(int A = (S-1)&S; A; A = (A-1)&S)
{
int B = S ^ A;
rep(i, n) chmin(dp[S][i], dp[A][i] + dp[B][i]);
}
rep(i, n)
{
if(dp[S][i] == INF) continue;
pq.emplace(dp[S][i], i);
}
while(!pq.empty())
{
auto [d, u] = pq.top();
pq.pop();
if(determined[S][u]) continue;
dp[S][u] = d;
determined[S][u] = true;
for(auto [v, c] : g[u])
{
if(d + c >= dp[S][v]) continue;
dp[S][v] = d + c;
pq.emplace(d + c, v);
}
}
}
cout << dp[(1<<t)-1][v[0]] << "\n";
return 0;
}
else
{
struct edge {int u, v, c;};
auto spanning_tree = [&](ll S) -> ll
{
vector<edge> e;
rep(u, n) if(S & (1LL<<u)) for(auto [v, c] : g[u]) if(S & (1LL<<v)) e.push_back({u, v, c});
sort(all(e), [](edge a, edge b){return a.c < b.c;});
int ans = 0;
int group = popcount((ull)S);
dsu uf(n);
for(auto [u, v, c] : e)
{
if(uf.same(u, v)) continue;
ans += c;
uf.merge(u, v);
--group;
}
if(group == 1) return ans;
else return INF;
};
ll T = 0;
for(int x : v) T |= 1LL<<x;
ll R = ((1LL<<n)-1) ^ T;
ll ans = LINF;
for(ll C = R; ; C = (C-1)&R)
{
chmin(ans, spanning_tree(T | C));
if(C == 0) break;
}
cout << ans << "\n";
return 0;
}
}