結果
| 問題 |
No.114 遠い未来
|
| コンテスト | |
| ユーザー |
HIR180
|
| 提出日時 | 2020-04-22 14:21:25 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 2,226 ms / 5,000 ms |
| コード長 | 3,161 bytes |
| コンパイル時間 | 2,707 ms |
| コンパイル使用メモリ | 227,240 KB |
| 最終ジャッジ日時 | 2025-01-09 22:29:45 |
|
ジャッジサーバーID (参考情報) |
judge5 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 25 |
ソースコード
//Let's join Kaede Takagaki Fan Club !!
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
typedef pair<int,P> P1;
typedef pair<P,P> P2;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 1000000000
#define fi first
#define sc second
#define rep(i,x) for(int i=0;i<x;i++)
#define repn(i,x) for(int i=1;i<=x;i++)
#define SORT(x) sort(x.begin(),x.end())
#define ERASE(x) x.erase(unique(x.begin(),x.end()),x.end())
#define POSL(x,v) (lower_bound(x.begin(),x.end(),v)-x.begin())
#define POSU(x,v) (upper_bound(x.begin(),x.end(),v)-x.begin())
#define all(x) x.begin(),x.end()
template<class T>
void dmp(T a){
rep(i,a.size()) cout << a[i] << " ";
cout << endl;
}
template<class T>
bool chmax(T&a, T b){
if(a < b){
a = b;
return 1;
}
return 0;
}
template<class T>
bool chmin(T&a, T b){
if(a > b){
a = b;
return 1;
}
return 0;
}
template<class T>
void g(T &a){
cin >> a;
}
template<class T>
void o(const T &a,bool space=false){
cout << a << (space?' ':'\n');
}
//ios::sync_with_stdio(false);
const ll mod = 1000000007;//998244353
template<class T>
void add(T&a,T b){
a+=b;
if(a >= mod) a-=mod;
}
int n, m, t;
int w[36][36];
vector<P1>edge;
vector<int>imp;
int dp[(1<<16)][36];
void solve_steiner(){
repn(i, (1<<16)-1) rep(j, 36) dp[i][j] = INF;
rep(i, imp.size()){
rep(j, n){
dp[(1<<i)][j] = w[imp[i]][j];
}
}
for(int x=0;x<(1<<t);x++){
if(__builtin_popcount(x) <= 1) continue;
int sub = x;
while(1){
rep(y, n) chmin(dp[x][y], dp[sub][y] + dp[sub^x][y]);
if(sub == 0) break;
sub = (sub-1) & x;
}
rep(y, n) rep(z, n){
chmin(dp[x][y], dp[x][z] + w[y][z]);
}
}
int ans = INF;
rep(x, n) chmin(ans, dp[(1<<t)-1][x]);
cout << ans << endl;
}
struct uf{
int par[36];
void init(){ rep(i, 36) par[i] = i; }
int find(int x){ if(x == par[x]) return x; else return par[x] = find(par[x]); }
void unite(int x, int y){
x = find(x); y = find(y); if(x == y) return;
par[x] = y;
}
bool same(int x, int y){ return find(x) == find(y); }
}kaede;
void solve_MST(){
vector<int>ump;
bool ex[36]={};
rep(i, imp.size()) ex[imp[i]] = 1;
rep(i, n) if(!ex[i]) ump.pb(i);
int sz = ump.size(), ans = INF;
rep(mask, (1<<sz)){
int N = t + __builtin_popcount(mask);
int cnt = 0, use = 0;
bool eex[36] = {};
rep(i, sz) if(((mask>>i)&1)) eex[ump[i]] = 1;
kaede.init();
rep(i, edge.size()){
int a = edge[i].sc.fi, b = edge[i].sc.sc;
if(!ex[a] && !eex[a]) continue;
if(!ex[b] && !eex[b]) continue;
if(kaede.same(a, b)) continue;
kaede.unite(a, b);
cnt ++;
use += edge[i].fi;
}
if(cnt == N-1) chmin(ans, use);
}
cout << ans << endl;
}
int main(){
cin >> n >> m >> t;
rep(i, 36) rep(j, 36){
if(i != j) w[i][j] = 1e7;
}
rep(i, m){
int a, b, c; cin >> a >> b >> c;
a --; b --;
w[a][b] = w[b][a] = c;
edge.pb(mp(c, mp(a, b)));
}
sort(all(edge));
imp.resize(t);
rep(i, t){
cin >> imp[i];
imp[i] --;
}
rep(x, n) rep(i, n) rep(j, n) chmin(w[i][j], w[i][x] + w[x][j]);
if(t <= 16) solve_steiner();
else solve_MST();
}
HIR180