Problem:
Water Pipe Construction
21XX 年，ついに人類は火星への移住計画を開始させた．火星への移住第一陣に選抜されたあなたは，火星行政中央局（the Administrative Center of Mars）に配属され，火星で起こる様々な問題に対処している．行政中央局の目下の最大の問題は自立した需要供給サイクルの確保である．月からの援助物資が届くまでには数ヶ月単位の時間がかかるため，基本的には火星内の需要は火星内で解決する必要がある．それに加えて，循環システムを確立するまでは資源を極力節約することが求められる．
行政中央局は極地にある氷の採掘を開始した．太陽光でこれを溶かし，水として個々の基地に供給することが最終目標である．最初の段階として，水源のある基地から2つの主要基地までの導水管を敷設することにした．また，現時点ではいくつかの基地とそれらを結ぶ道路以外には開拓されておらず，未開拓のところに導水管を敷設するには多大なるコストと燃料を要するため，道路に沿って導水管を敷設することにした．さらに，技術上の制約のため，彼らの導水管は常に一方向だけに水が流れる．
あなたの仕事は，これらの条件のもとで，導水管の敷設にかかるコストを最小にするプログラムを作成することである．
Input
入力は複数のデータセットから構成される．
データセットの最初の行は 5 つの整数からなる．これらは順に，火星に存在する基地の数
n
(3 <=
n
<= 100)，基地を結ぶ道路の数
m
(2 <=
m
<= 1000)，水源となる基地の番号
s
， 導水管の目的地となる 2 つの主要基地の番号
g
1
，
g
2
を表す．基地の番号は 1 から
n
までの整数で表される．
s
，
g
1
，
g
2
は互いに異なる．
続く
m
行には，導水管を敷設可能な道路の情報が与えられる．各行はある 2 つの基地間における道路の情報を表しており，3 つの整数
b
1
，
b
2
，
c
(1 <=
c
<= 1000) からなる．ここに
b
1
，
b
2
は道路の始端および終端の基地の番号を表し，これらは互いに異なる．
c
は基地
b
1
から基地
b
2
に向かう導水管を敷設するためにかかるコストである．
全てのデータセットについて，水源から目的地まで水を供給する経路は常に存在すると仮定してよい．また，ある 2 つの基地間には高々 1 つの道路しか存在しないことから，コストの情報はそれぞれの方向について高々 1 回しか与えられない．
入力の終了はスペース文字で区切られた 5 つのゼロが含まれる行で表される．
Output
それぞれのデータセットに対して，導水管を敷設するコストの最小値を 1 行に出力せよ．
Sample Input
4 5 1 3 4
1 2 5
2 3 5
2 4 5
1 3 8
1 4 8
0 0 0 0 0
Output for the Sample Input
15

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;

using VS = vector<string>;    using LL = long long;
using VI = vector<int>;       using VVI = vector<VI>;
using PII = pair<int, int>;   using PLL = pair<LL, LL>;
using VL = vector<LL>;        using VVL = vector<VL>;

#define ALL(a)  begin((a)),end((a))
#define RALL(a) (a).rbegin(), (a).rend()
#define SZ(a) int((a).size())
#define SORT(c) sort(ALL((c)))
#define RSORT(c) sort(RALL((c)))
#define UNIQ(c) (c).erase(unique(ALL((c))), end((c)))
#define FOR(i, s, e) for (int(i) = (s); (i) < (e); (i)++)
#define FORR(i, s, e) for (int(i) = (s); (i) > (e); (i)--)
#define debug(x) cerr << #x << ": " << x << endl
const int INF = 1e9;                          const LL LINF = 1e16;
const LL MOD = 1000000007;                    const double PI = acos(-1.0);
int DX[8] = { 0, 0, 1, -1, 1, 1, -1, -1 };    int DY[8] = { 1, -1, 0, 0, 1, -1, 1, -1 };

/* -----  2018/07/23  Problem: AOJ 2005 / Link: https://onlinejudge.u-aizu.ac.jp/challenges/search/volumes/2005  ----- */
/* ------問題------

21XX 年，ついに人類は火星への移住計画を開始させた．火星への移住第一陣に選抜されたあなたは，火星行政中央局（the Administrative Center of Mars）に配属され，火星で起こる様々な問題に対処している．行政中央局の目下の最大の問題は自立した需要供給サイクルの確保である．月からの援助物資が届くまでには数ヶ月単位の時間がかかるため，基本的には火星内の需要は火星内で解決する必要がある．それに加えて，循環システムを確立するまでは資源を極力節約することが求められる．
行政中央局は極地にある氷の採掘を開始した．太陽光でこれを溶かし，水として個々の基地に供給することが最終目標である．最初の段階として，水源のある基地から2つの主要基地までの導水管を敷設することにした．また，現時点ではいくつかの基地とそれらを結ぶ道路以外には開拓されておらず，未開拓のところに導水管を敷設するには多大なるコストと燃料を要するため，道路に沿って導水管を敷設することにした．さらに，技術上の制約のため，彼らの導水管は常に一方向だけに水が流れる．
あなたの仕事は，これらの条件のもとで，導水管の敷設にかかるコストを最小にするプログラムを作成することである．

-----問題ここまで----- */
/* -----解説等-----

日本語が悪いのでSやGiから水が分かれるとも取れる。
×彼らの導水管は常に一方向だけに水が流れる
○頂点を流れる水は常に一方向である
頂点について一方向だと、分岐点を全探索するのみ。

----解説ここまで---- */


int main() {
	cin.tie(0);
	ios_base::sync_with_stdio(false);


	int N, M, S, G1, G2;
	while (cin >> N >> M >> S >> G1 >> G2,N) {
		const int intINF = 2e9 / 3;
		VVI dist(N, VI(N,intINF ));
		S--, G1--, G2--;
		FOR(i, 0, N)dist[i][i] = 0;
		FOR(i, 0, M) {
			int a, b, c; cin >> a >> b >> c; a--; b--;
			dist[a][b] = c;
		}
		FOR(k, 0, N)FOR(i, 0, N)FOR(j, 0, N)dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
		int ans = INF;
		FOR(i, 0, N) {
			ans = min(ans, dist[S][i] + dist[i][G1] + dist[i][G2]);
		}
		cout << ans << "\n";

	}

	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3436
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;

bool solve() {
    int N, M, S, T1, T2;
    cin >> N >> M >> S >> T1 >> T2;
    if (N == 0) return false;
    S--, T1--, T2--;
    const long long inf = 1e18;
    vector<vector<long long>> D(N, vector<long long>(N, inf));
    vector<vector<long long>> E(N, vector<long long>(N, inf));
    for (int u, v, w; M--; ) {
        cin >> u >> v >> w;
        u--, v--;
        D[u][v] = w;
        E[v][u] = w;
    }
    for (int i = 0; i < N; i++) {
        D[i][i] = 0;
        E[i][i] = 0;
    }
    for (int k = 0; k < N; k++) {
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                D[i][j] = min(D[i][j], D[i][k] + D[k][j]);
                E[i][j] = min(E[i][j], E[i][k] + E[k][j]);
            }
        }
    }
    long long ans = inf;
    for (int i = 0; i < N; i++) {
        ans = min(ans, E[i][S] + D[i][T1] + D[i][T2]);
    }
    cout << ans << endl;
    return true;
}

int main() {
    while (solve()) {}
}
accuracy: 1
time_ms: 60
memory_kb: 3712
final_rank: 19

code_snippet: // (⁠◕⁠ᴗ⁠◕⁠✿⁠)

// #pragma GCC target("avx2")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define srep(i, s, n) for (ll i = s; i < (n); i++)
#define len(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
using namespace std;
template<typename T> using vc = vector<T>;
template<typename T> using vv = vc<vc<T>>;
template<typename T> using vvv = vv<vc<T>>;
using vi = vc<int>;using vvi = vv<int>; using vvvi = vv<vi>;
using ll = long long;using vl = vc<ll>;using vvl = vv<ll>; using vvvl = vv<vl>;
using ld = long double; using vld = vc<ld>; using vvld = vc<vld>; using vvvld = vc<vvld>;
using uint = unsigned int;
using ull = unsigned long long;
const ld pi = 3.141592653589793;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
// const ll mod = 1000000007;
const ll mod = 998244353;
inline bool inside(ll y, ll x, ll H, ll W) {return 0 <= (y) and (y) < (H) and 0 <= (x) and (x) < (W); }

#define debug(var)  do{std::cout << #var << " : \n";view(var);}while(0)
template<typename T> void view(T e){cout << e << endl;}
template<typename T> void view(const vc<T>& v){for(const auto& e : v){ cout << e << " "; } cout << endl;}
template<typename T> void view(const vv<T>& vv){ for(const auto& v : vv){ view(v); } }

tuple<vl, vi> dijkstra(int s, int N, vv<pair<int, ll>> &g){
    using P = pair<ll, int>;
    vl dist(N, INF);
    vi bef(N);
    priority_queue<P, vc<P>, greater<P>> q;
    dist[s] = 0;
    q.push({0, s});
    while (!q.empty()){
        auto [c, now] = q.top();q.pop();
        if (dist[now] < c) continue;
        for (auto&& [nxt, nc]: g[now]) if (dist[nxt] > c + nc){
            dist[nxt] = c + nc;
            bef[nxt] = now;
            q.push({dist[nxt], nxt}); 
        }
    }
    return {dist, bef};
}

int N, M, s, g1, g2;

void solve(){
    vv<pair<int, ll>> g(N), rg(N);
    rep(i, M){
        int a, b, w; cin >> a >> b >> w; a--; b--;
        g[a].push_back({b, w});
        rg[b].push_back({a, w});
    }
    auto [dist_s, _s] = dijkstra(s, N, g);
    auto [dist_g1, _g1] = dijkstra(g1, N, rg);
    auto [dist_g2, _g2] = dijkstra(g2, N, rg);
    ll ans = INF;
    rep(p, N) if (dist_s[p] < INF && dist_g1[p] < INF && dist_g2[p] < INF){
        ans = min(ans, dist_s[p] + dist_g1[p] + dist_g2[p]);
    }
    cout << ans << endl;
}
int main(){
    while (true){
        cin >> N >> M >> s >> g1 >> g2;
        s--;
        g1--;
        g2--;
        if (N == 0) break;
        solve();
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3584
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define rrep(i,start,end) for (ll i = start;i >= (ll)(end);i--)
#define repn(i,end) for(ll i = 0; i <= (ll)(end); i++)
#define reps(i,start,end) for(ll i = start; i < (ll)(end); i++)
#define repsn(i,start,end) for(ll i = start; i <= (ll)(end); i++)
#define each(p,a) for(auto &p:a)
typedef vector<ll> vll;
typedef vector<pair<ll ,ll>> vpll;
typedef vector<vector<ll>> vvll;
typedef set<ll> sll;
typedef map<ll , ll> mpll;
typedef pair<ll ,ll> pll;
typedef tuple<ll , ll , ll> tpl3;
#define LL(...) ll __VA_ARGS__; input(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__; input(__VA_ARGS__)
#define Str(...) string __VA_ARGS__; input(__VA_ARGS__)
#define Ch(...) char __VA_ARGS__; input(__VA_ARGS__)
#define all(a)  (a).begin(),(a).end()
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define sz(x) (ll)x.size()
// << std::fixed << std::setprecision(10)
const ll INF = 1LL << 60;
const ld EPS = 1e-9;
 
ll lceil(ll a,ll b){if(a%b==0){return a/b;}if(a>=0){return (a/b)+1;}else{return -((-a)/b);}}
ll lfloor(ll a,ll b){if(a%b==0){return a/b;}if(a>=0){return (a/b);}else{return -((-a)/b)-1;}}
inline ll positive_mod(ll a,ll m){return (a % m + m)%m;}
inline ll popcnt(ull a){ return __builtin_popcountll(a);}
//0indexed
inline ll topbit(ll a){assert(a != 0);return 63 - __builtin_clzll(a);}
inline ll smlbit(ll a){assert(a != 0);return __builtin_ctzll(a);}
template<class T> bool chmin(T& a, T b){if(a > b){a = b;return true;}return false;}
template<class T> bool chmax(T& a, T b){if(a < b){a = b;return true;}return false;}
template<typename T> std::istream &operator>>(std::istream&is,std::vector<T>&v){for(T &in:v){is>>in;}return is;}
template<typename T> std::ostream &operator<<(std::ostream&os,const std::vector<T>&v){for(auto it=std::begin(v);it!=std::end(v);){os<<*it<<((++it)!=std::end(v)?" ":"");}return os;}
template<typename T1, typename T2>std::ostream &operator<< (std::ostream &os, std::pair<T1,T2> p){os << "{" << p.first << "," << p.second << "}";return os;}
template<class... T>void input(T&... a){(cin >> ... >> a);}
void print(){cout << endl;}
template<class T, class... Ts>void print(const T& a, const Ts&... b){cout << a;((cout << ' ' << b), ...);cout << endl;}
template<class T> void pspace(const T& a){ cout << a << ' ';}
void perr(){cerr << endl;}
template<class T, class... Ts>void perr(const T& a, const Ts&... b){cerr << a;((cerr << ' ' << b), ...);cerr << endl;}
void yes(bool i = true){ return print(i?"yes":"no"); }
void Yes(bool i = true){ return print(i?"Yes":"No"); }
void YES(bool i = true){ return print(i?"YES":"NO"); }
template <class T> vector<T> &operator++(vector<T> &v) {for(auto &e : v) e++;return v;}
template <class T> vector<T> operator++(vector<T> &v, signed) {auto res = v;for(auto &e : v) e++;return res;}
template <class T> vector<T> &operator--(vector<T> &v) {for(auto &e : v) e--;return v;}
template <class T> vector<T> operator--(vector<T> &v, signed) {auto res = v;for(auto &e : v) e--;return res;}
//grid探索用
vector<ll> _ta = {0,0,1,-1,1,1,-1,-1};
vector<ll> _yo = {1,-1,0,0,1,-1,1,-1};
bool isin(ll now_i,ll now_j,ll h,ll w){return (0<=now_i && now_i < h && 0 <= now_j && now_j < w);}
  
ll lpow(ll x,ll n){ll ans = 1;while(n >0){if(n & 1)ans *= x;x *= x;n >>= 1;}return ans;}
ll Modlpow(ll x,ll n,ll m){ll ans = 1;ll a = x%m;while(n >0){if(n & 1){ans *= a;ans%= m;}a *= a;a %= m;n >>= 1;}return ans;} 
const ll MOD9 = 998244353LL;
const ll MOD10 = 1000000007LL;
// for AOJ or ICPC or etc..
template<class Tp>
bool zero (const Tp &x) {
    return x == 0;
}

template<class Tp, class... Args>
bool zero (const Tp &x, const Args& ...args) {
    return zero(x) and zero(args...);
}


/*隣接行列を更新してくDPのイメージ
つながってない辺は重みINF、繋がってたら辺の重みで初期化
O(V^3)
*/
int warshall_floyd(vector<vector<ll>> &dist){
  int size = (int)dist.size();
  rep(k,size){
    rep(i,size){
      rep(j,size){
        if(i == j){
          chmin(dist[i][j],0LL);
        }
        if(dist[i][k] != INF && dist[k][j] != INF){
          chmin(dist[i][j],dist[i][k] + dist[k][j]);
        }
      }
    }
  }
  //負の閉路判定あれば−1大丈夫なら1
  rep(i,size){
    if(dist[i][i]<0){
      return -1;
    }
  }
  return 1;
}
 
int main(){
  ios::sync_with_stdio(false);cin.tie(nullptr);
  while(true){
    LL(n,m,s,g1,g2);
    if(zero(n,m,s,g1,g2))break;
    s--;g1--;g2--;
    vvll g(n,vll(n,INF));
    rep(i,m){
      LL(a,b,c);
      a--;b--;
      chmin(g[a][b],c);
    }
    warshall_floyd(g);
    // iまで一緒
    ll ans = INF;

    rep(i,n){
      chmin(ans,g[s][i] + g[i][g1] + g[i][g2]);
    }
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 40
memory_kb: 3840
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = 1LL << 40;

bool solve(){
    int n, m, s, g1, g2; cin >> n >> m >> s >> g1 >> g2, --s, --g1, --g2;
    if(n == 0) return false;
    vector G(n, vector<ll>(n, INF));
    for(int i = 0; i < m; ++i){
        int b1, b2, c; cin >> b1 >> b2 >> c, --b1, --b2;
        G[b1][b2] = c;
    }

    for(int i = 0; i < n; ++i) G[i][i] = 0;
    for(int k = 0; k < n; ++k){
        for(int i = 0; i < n; ++i){
            for(int j = 0; j < n; ++j){
                if(G[i][j] > G[i][k] + G[k][j]){
                    G[i][j] = G[i][k] + G[k][j];
                }
            }
        }
    }
    ll ans = INF;
    for(int i = 0; i < n; ++i){
        ll tmp = G[s][i] + G[i][g1] + G[i][g2];
        if(ans > tmp) ans = tmp;
    }
    cout << ans << endl;
    return true;
}

int main(){
    while(1){
        if(!solve()) break;
    }
}
accuracy: 1
time_ms: 50
memory_kb: 3320
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

const ll INF = 1e18;
int n, m, s, g1, g2;
vector<vector<pair<ll, ll>>> E;

vector<ll> dijk(int s) {
  vector<ll> dist(n, INF);
  priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<>> pq;
  pq.emplace(0, s);
  dist[s] = 0;
  while (!pq.empty()) {
    auto [cost, u] = pq.top();
    pq.pop();
    if (dist[u] != cost)
      continue;
    for (auto [v, w] : E[u]) {
      if (dist[v] > cost + w) {
        dist[v] = cost + w;
        pq.emplace(dist[v], v);
      }
    }
  }
  return dist;
}

int main() {
  while (true) {
    n = m = s = g1 = g2 = 0;
    cin >> n >> m >> s >> g1 >> g2, s--, g1--, g2--;
    if (n == 0) {
      break;
    }

    E.clear();
    E.resize(n);
    for (int i = 0; i < m; i++) {
      int a, b, c;
      cin >> a >> b >> c, a--, b--;
      E[a].emplace_back(b, c);
    }

    auto d1 = dijk(s);

    ll ans = INF;
    for (int i = 0; i < n; i++) {
      auto d2 = dijk(i);
      ans = min(ans, d1[i] + d2[g1] + d2[g2]);
    }
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 30
memory_kb: 3516
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

const ll INF = 1e18;

vector<ll> dijk(int s, int n, int m, int g1, int g2,
                vector<vector<pair<ll, ll>>> &E) {
  vector<ll> dist(n, INF);
  priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<>> pq;
  pq.emplace(0, s);
  dist[s] = 0;
  while (!pq.empty()) {
    auto [cost, u] = pq.top();
    pq.pop();
    if (dist[u] != cost)
      continue;
    for (auto [v, w] : E[u]) {
      if (dist[v] > cost + w) {
        dist[v] = cost + w;
        pq.emplace(dist[v], v);
      }
    }
  }
  return dist;
}

int main() {
  while (true) {
    int n, m, s, g1, g2;
    cin >> n >> m >> s >> g1 >> g2, s--, g1--, g2--;
    if (n == 0) {
      break;
    }
    vector<vector<pair<ll, ll>>> E(n);
    for (int i = 0; i < m; i++) {
      int a, b, c;
      cin >> a >> b >> c, a--, b--;
      E[a].emplace_back(b, c);
    }

    auto d1 = dijk(s, n, m, g1, g2, E);

    ll ans = INF;
    for (int i = 0; i < n; i++) {
      auto d2 = dijk(i, n, m, g1, g2, E);
      ans = min(ans, d1[i] + d2[g1] + d2[g2]);
    }
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 30
memory_kb: 3220
final_rank: 4

code_snippet: #include <iostream>
#include <vector>

using namespace std;
using Mat = vector<vector<int>>;

void wf(Mat &a, int n) {
    for (int k = 0; k < n; k++) {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                a[i][j] = min(a[i][j], a[i][k] + a[k][j]);
            }
        }
    }
}

constexpr int inf = 1 << 29;
void solve(int n, int m, int s, int g1, int g2) {
    s--,g1--,g2--;
    Mat dist(n, vector<int>(n, inf));
    for (int i = 0; i < n; i++) dist[i][i] = 0;
    while(m--) {
        int u, v, c;
        cin >> u >> v >> c;
        u--,v--;
        dist[u][v] = c;
    }
    wf(dist, n);
    int ans = inf;
    for (int i = 0; i < n; i++) {
        ans = min(ans, dist[s][i] + dist[i][g1] + dist[i][g2]);
    }
    cout << ans << endl;
}

int main() {
    int n, m, s, g1, g2;
    cin >> n >> m >> s >> g1 >> g2;
    do {
        solve(n, m, s, g1, g2);
        cin >> n >> m >> s >> g1 >> g2;
    }while (n != 0);
}
accuracy: 1
time_ms: 40
memory_kb: 3300
final_rank: 10

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

#include <unistd.h>

namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf


uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio


using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */

struct MaxFlow {
    struct Edge {
        int to, rev;
        ll cap;
    };
    int V;
    vector<vector<Edge>> G;
    vector<int> itr, level;
    using P = pair<int, int>;
    vector<P> es;

  public:
    MaxFlow() {}
    MaxFlow(int V) : V(V) {
        G.assign(V, vector<Edge>());
    }
    int add_vertex() {
        G.push_back(vector<Edge>());
        return V++;
    }
    void add_edge(int from, int to, ll cap) {
        int fid = SZ(G[from]), tid = SZ(G[to]);
        if (from == to)
            tid++;
        es.push_back({from, fid});
        G[from].push_back({to, tid, cap});
        G[to].push_back({from, fid, 0});
    }
    struct Type {
        int from, to;
        ll cap, recap;
    };
    Type get_edge(int i) {
        auto [from, pos] = es[i];
        auto e = G[from][pos];
        auto re = G[e.to][e.rev];
        return Type{from, e.to, e.cap, re.cap};
    }
    void bfs(int s) {
        level.assign(V, -1);
        queue<int> q;
        level[s] = 0;
        q.push(s);
        while (!q.empty()) {
            int v = q.front();
            q.pop();
            for (auto &e : G[v]) {
                if (e.cap > 0 && level[e.to] < 0) {
                    level[e.to] = level[v] + 1;
                    q.push(e.to);
                }
            }
        }
    }
    ll dfs(int v, int t, ll f) {
        if (v == t)
            return f;
        for (int &i = itr[v]; i < (int)G[v].size(); i++) {
            Edge &e = G[v][i];
            if (e.cap > 0 && level[v] < level[e.to]) {
                ll d = dfs(e.to, t, min(f, e.cap));
                if (d > 0) {
                    e.cap -= d, G[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }
    ll run(int s, int t) {
        ll ret = 0, f;
        while (bfs(s), level[t] >= 0) {
            itr.assign(V, 0);
            while ((f = dfs(s, t, INF)) > 0)
                ret += f;
        }
        return ret;
    }
    vector<int> cut() {
        vector<int> ret(V);
        rep(v, 0, V) if (level[v] < 0) ret[v] = 1;
        return ret;
    }
};

/**
 * @brief Maximum Flow
 */

vector<int> Dijkstra(int N, vector<vector<pair<int,int>>>& G, int S) {
    vector<int> D(N, inf);
    priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> PQ;
    D[S] = 0;
    PQ.push({0,S});
    while(!PQ.empty()) {
        pair<int,int> P = PQ.top();
        PQ.pop();
        if (D[P.second] < P.first) continue;
        for (pair<int,int> E : G[P.second]) {
            int ND = P.first + E.second;
            if (ND < D[E.first]) {
                D[E.first] = ND;
                PQ.push({ND,E.first});
            }
        }
    }
    return D;
}

int main() {
while(1) {
    int N, M, S, G1, G2;
    cin >> N >> M >> S >> G1 >> G2;
    if (N == 0) return 0;
    S--, G1--, G2--;
    vector<vector<pair<int,int>>> A(N), B(N);
    rep(i,0,M) {
        int X, Y, Z;
        cin >> X >> Y >> Z;
        X--, Y--;
        A[X].push_back({Y,Z});
        B[Y].push_back({X,Z});
    }
    vector<int> D1 = Dijkstra(N,A,S), D2 = Dijkstra(N,B,G1), D3 = Dijkstra(N,B,G2);
    ll ANS = INF;
    rep(i,0,N) {
        chmin(ANS,(ll)D1[i] + (ll)D2[i] + (ll)D3[i]);
    }
    cout << ANS << endl;
}
}
accuracy: 1
time_ms: 10
memory_kb: 3456
final_rank: 2

code_snippet: // (⁠◕⁠ᴗ⁠◕⁠✿⁠)

#include <bits/stdc++.h>
// #pragma GCC target("avx2")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("unroll-loops")
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define srep(i, s, n) for (ll i = s; i < (n); i++)
#define len(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
using namespace std;
template<typename T> using vc = vector<T>;
template<typename T> using vv = vc<vc<T>>;
template<typename T> using vvv = vv<vc<T>>;
using vi = vc<int>;using vvi = vv<int>; using vvvi = vv<vi>;
using ll = long long;using vl = vc<ll>;using vvl = vv<ll>; using vvvl = vv<vl>;
using ld = long double; using vld = vc<ld>; using vvld = vc<vld>; using vvvld = vc<vvld>;
using uint = unsigned int;
using ull = unsigned long long;
const ld pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
// const ll mod = 1000000007;
const ll mod = 998244353;
inline bool inside(ll y, ll x, ll H, ll W) {return 0 <= (y) and (y) < (H) and 0 <= (x) and (x) < (W); }

#define debug(var)  do{std::cout << #var << " : \n";view(var);}while(0)
template<typename T> void view(T e){cout << e << endl;}
template<typename T> void view(const vc<T>& v){for(const auto& e : v){ cout << e << " "; } cout << endl;}
template<typename T> void view(const vv<T>& vv){ for(const auto& v : vv){ view(v); } }

int solve(int N, int M, int S, int G1, int G2){
    vvi dist(N, vi(N, inf));
    rep(i, N) dist[i][i] = 0;
    rep(i, M){
        int u, v, c; cin >> u >> v >> c; u--; v--;
        dist[u][v] = c;
    }
    for (int k = 0; k < N; k++) for (int i = 0; i < N; i++) for (int j = 0; j < N; j++){
        if (dist[i][k] != inf && dist[k][j] != inf){
            if (dist[i][j] > dist[i][k] + dist[k][j]){
                dist[i][j] = dist[i][k] + dist[k][j];
            }
        }
    }
    int ans = inf;
    rep(i, N) if (dist[S][i] != inf && dist[i][G1] != inf && dist[i][G2] != inf){
        ans = min(ans, dist[S][i] + dist[i][G1] + dist[i][G2]);
    }
    return ans;
}
int main(){
    vi ans;
    while (true){
        int N, M, S, G1, G2; cin >> N >> M >> S >> G1 >> G2;
        S--; G1--; G2--;
        if (N == 0) break;
        ans.push_back(solve(N, M, S, G1, G2));
    }
    for (auto x : ans) cout << x << endl;
}
accuracy: 1
time_ms: 50
memory_kb: 3296
final_rank: 16

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
using namespace std;

using ll = long long;
using i64 = long long;
using pll = pair<ll,ll>;
using plll = pair<pll,ll>;
using pii =pair<int,int>;

constexpr ll mod = 1000000007;

int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
int dX[4]={1,0,-1,0};
int dY[4]={0,-1,0,1};



//library

//end

using Graph =vector<vector<int>>;
int big=500000000;

int main(){

    while (true){
        int n,m,s,g1,g2;
        cin>>n>>m>>s>>g1>>g2;
        if (n==0)break;
        vector<vector<int>> E(n+1,vector<int>(n+1,big));
        for (int i=0; i<n+1; i++){
            E[i][i]=0;
        }
        for (int i=0; i<m; i++){
            int b1,b2,c;
            cin>>b1>>b2>>c;
            E[b1][b2]=c;
        }
        for (int k=0; k<n+1; k++){
            for (int i=0; i<n+1; i++){
                for (int j=0; j<n+1; j++){
                    E[i][j]=min(E[i][j],E[i][k]+E[k][j]);
                }
            }
        }

        int ans=big;
        for (int v=1; v<n+1; v++){
            ans=min(ans,E[s][v]+E[v][g1]+E[v][g2]);
        }

        cout<<ans<<endl;

    }

    return 0;

}
accuracy: 1
time_ms: 40
memory_kb: 3532
final_rank: 12

code_snippet: #include <bits/stdc++.h>
//#include <ranges>
#define _USE_MATH_DEFINES
//#include <atcoder/all>
//#include <atcoder/modint>
//using namespace atcoder;
//using mint = modint998244353;
//using mint = modint1000000007;
using namespace std;
//using mint = modint;
using ll = long long;
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define rep2(i, s, n) for (ll i = (s); i < (ll)(n); i++)
#define rrep(i,a,b) for(int i=a;i>=b;i--)
#define fore(i,a) for(auto &i:a)
#define V vector<ll>
#define Vi vector<int>
#define Vd vector<double>
#define Vb vector<bool>
#define Vs vector<string>
#define Vc vector<char>
#define VV vector<V>
using P = pair<ll,ll>;
using G = vector<vector<int>>;
#define VP vector<P>
template<typename T> using min_priority_queue = priority_queue<T, vector<T>, greater<T>>;
#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define INF 1LL << 60
#define inf 1e9
template <typename T>
bool chmax(T &a, const T& b) {
  if (a < b) {
    a = b;  // aをbで更新
    return true;
  }
return false;
}
template <typename T>
bool chmin(T &a, const T& b) {
  if (a > b) {
    a = b;  // aをbで更新
    return true;
  }
  return false;
}

long long combi(long long n, long long k) {
  if (n == k || k == 0)
    return 1;
  else {
    return combi(n - 1, k - 1) + combi(n - 1, k);
  }
}
//整数かどうか
bool isNumber(const string& str)
{
  for (const char &c : str) {
        if (std::isdigit(c) == 0) return false;
    }
    return true;
}
///*
//最大公約数
ll gcd(ll a, ll b){
  if(b==0){
    return a;
  }else{
    return gcd(b, a%b);
  }
}
//最小公倍数
ll lcm(ll a, ll b){
  ll g=gcd(a,b);
  return a/g*b;
}
//*/
//int di[] = {-1,0,1,0};
//int dj[] = {0,-1,0,1};

//s = regex_replace(s, regex("あ"), "う");
/*stiring で char を検索するときは
    s.find(c)!=string::npos
 */


/*//各桁の和
 int wa(int n){
  int sum =0;
  while(n>0){
    sum += n%10;
    n/=10;
  }
  return sum;
}
*/
/*
//階乗
 int ki(int i){
   int k = 1;
   for(int j = 1; j<=i; j++){
     k *= j;
   }
   return k;
 }
*/
/*log_x(b)
double logN(double x, double b) {
    return log(x) / log(b);
}
*/
//
/*//エラトステネスの篩 main関数内にsolve();を書き込む!!
const ll N = 101010;//求める範囲
Vb isp(N+1,true);
void solve(){
  isp[0] = false;
  isp[1] = false;
  for(ll i = 2; i+i<=N;i++){
    if(isp[i])for(ll j = 2; i*j<=N;j++)isp[i*j] = false;
  }
}
//
*/
//
/*
//約数列挙　O(√n)
vector<long long> divisor(long long n) {
    vector<long long> ret;
    for (long long i = 1; i * i <= n; i++) {
        if (n % i == 0) {
            ret.push_back(i);
            if (i * i != n) ret.push_back(n / i);
        }
    }
    sort(ret.begin(), ret.end()); // 昇順に並べる
    return ret;
}
//
*/
//
/*
//素因数分解O(√n)
map< ll, ll > prime_factor(ll n) {
  map< ll, ll > ret;
  for(ll i = 2; i * i <= n; i++) {
    while(n % i == 0) {
      ret[i]++;
      n /= i;
    }
  }
  if(n != 1) ret[n] = 1;
  return ret;
}
//
*/

/*
ll modpow(ll x, ll n, ll mod){
 while(n){
   ll resu = 1;
   if(n&1)res = (res * x) %mod;
   x = (x*x)%mod;
   n>>=1;
 }
 return res;
}
*/
/*
//最小二乗法
//aのb乗をmで割ったあまりを返す関数
//変数aはa^1→a^2→a^4→a^8→…と変化
ll power(ll a,ll b, ll m){
  ll p = a,ans = 1;
  rep(i,60){
    ll wari = (1LL<<i);
    if((b/wari)%2==1){
      ans=(ans*p)%m;
    }
    p=(p*p)%m;
  }
  return ans;
}
*/
//
/*
template <typename T> bool next_combination(const T first, const T last, int k) {
    const T subset = first + k;
    // empty container | k = 0 | k == n 
    if (first == last || first == subset || last == subset) {
        return false;
    }
    T src = subset;
    while (first != src) {
        src--;
        if (*src < *(last - 1)) {
            T dest = subset;
            while (*src >= *dest) {
                dest++;
            }
            iter_swap(src, dest);
            rotate(src + 1, dest + 1, last);
            rotate(subset, subset + (last - dest) - 1, last);
            return true;
        }
    }
    // restore
    rotate(first, subset, last);
    return false;
}
//
*/
int ctoi(char c){
  if(c=='1')return 1;
  else if(c=='2')return 2;
  else if(c=='3')return 3;
  else if(c=='4')return 4;
  else if(c=='5')return 5;
  else if(c=='6')return 6;
  else if(c=='7')return 7;
  else if(c=='8')return 8;
  else if(c=='9')return 9;
  else if(c=='0')return 0;
  else return -inf;
}
//vector<int> dx = {1,0,-1,0,1,-1,-1,1};
//vector<int> dy = {0,1,0,-1,1,1,-1,-1};
int dx[4] = { 0, 1, 0, -1 }, dy[4] = { -1, 0, 1, 0 };
//int dx[8]={0,-1,-1,-1,0,1,1,1},dy[8]={1,1,0,-1,-1,-1,0,1};
//#define mod 998244353
//cout << mint.val() << endl;
//cout << fixed << setprecision(15) << y << endl;

//bit s に i番目のビットを立てる
#define bittate(s,i) s | (1LL<<i)
//bit sから i番目のビットを消す
#define bitkeshi(s,i) s^(1LL<<i)
//bit s が i番目のビットを含んでいるか
#define bitcheck(s,i) (s>>i)&1LL
//string str(bitset<32>(value).to_string<char, char_traits<char>, allocator<char> >());
#define ppc(n) __popcount(n)
string tobin(ll n){
  string re((bitset<64>(n).to_string<char, char_traits<char>, allocator<char> >()));
  return re;
}
#define yes "Yes"
#define no "No"
#define Yes "YES"
#define No "NO"




int main(){
  int n,m,s,g1,g2;
  while(cin >> n >> m >> s >> g1 >> g2){
    if(n==0)return 0;
    s--;g1--;g2--;
    VV dis(n,V(n,INF));
    rep(i,m){
      int b1,b2,c;
      cin >> b1 >> b2 >> c;
      b1--;b2--;
      dis[b1][b2]=c;
    }
    rep(i,n)dis[i][i]=0;
    rep(i,n)rep(j,n)rep(k,n){
      dis[j][k]=min(dis[j][k],dis[j][i]+dis[i][k]);
    }
    ll ans=INF;
    rep(i,n){
      chmin(ans,dis[s][i]+dis[i][g1]+dis[i][g2]);
    }
    cout << ans << endl;

  }



}
accuracy: 1
time_ms: 40
memory_kb: 3532
final_rank: 12

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
using ll = long long;
#define MOD 1000000007
#define Mod 998244353
const int MAX = 1000000005;
const long long INF = 1000000000000000005LL;
using namespace std;
//using namespace atcoder;

vector<ll> dijkstra (int st, int N, vector<vector<pair<int, ll>>> &G) {
	vector<ll> dist(N, MAX);
	priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>> pq;
	dist[st] = 0;
	pq.push(make_pair(0, st));
	while (!pq.empty()) {
		ll d;
		int v;
		tie(d, v) = pq.top();
		pq.pop();
		if (d != dist[v]) continue;
		for (auto nv : G[v]) {
			if (dist[nv.first] <= dist[v]+nv.second) continue;
			dist[nv.first] = dist[v]+nv.second;
			pq.push(make_pair(dist[nv.first], nv.first));
		}
	}
	return dist;
}

bool solve() {
    int n, m, s, g1, g2;
    cin >> n >> m >> s >> g1 >> g2;
    if (n == 0) return false;
    s--; g1--; g2--;
    vector<vector<pair<int, ll>>> G(n);
    for (int i = 0; i < m; i++) {
        int u, v;
        ll c;
        cin >> u >> v >> c;
        u--; v--;
        G[u].push_back({v, c});
    }
    vector<vector<ll>> dist(n);
    for (int i = 0; i < n; i++) {
        dist[i] = dijkstra(i, n, G);
    }
    ll ans = INF;
    for (int i = 0; i < n; i++) {
        ans = min(ans, dist[s][i] + dist[i][g1] + dist[i][g2]);
    }
    cout << ans << endl;
    return true;
}

int main() {
    ios::sync_with_stdio(0);cin.tie();
    while (solve()) {}
}
accuracy: 1
time_ms: 30
memory_kb: 3592
final_rank: 8

code_snippet: #include <bits/stdc++.h>

int solve() {
    int n, m, s, g1, g2;
    std::cin >> n >> m >> s >> g1 >> g2;
    if (n == 0) return 1;
    s--; g1--; g2--;
    const int INF = 1e8;
    std::vector dist(n, std::vector<int>(n, INF));
    for (int i = 0; i < m; i++) {
        int u, v, c;
        std::cin >> u >> v >> c;
        u--; v--;
        dist[u][v] = c;
    }
    for (int i = 0; i < n; i++) dist[i][i] = 0;

    for (int k = 0; k < n; k++) {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                dist[i][j] = std::min(dist[i][j], dist[i][k] + dist[k][j]);
            }
        }
    }

    int ans = INF;
    for (int i = 0; i < n; i++) {
        ans = std::min(ans, dist[s][i] + dist[i][g1] + dist[i][g2]);
    }
    std::cout << ans << '\n';

    return 0;
}

int main() {
    while (!solve());
}
accuracy: 1
time_ms: 40
memory_kb: 3216
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
#define rep(i, a, b) for(ll i = a; i < b; ++i)
#define rrep(i, a, b) for(ll i = a; i >= b; --i)
constexpr ll inf = 4e18;
struct SetupIO {
    SetupIO() {
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout << fixed << setprecision(30);
    }
} setup_io;
int main(void) {
    while(true) {
        int n, m, s, g1, g2;
        cin >> n >> m >> s >> g1 >> g2;
        if(n == 0) break;
        s--;
        g1--;
        g2--;
        vector<vector<int>> d(n, vector<int>(n, 1e8));
        rep(i, 0, n) d[i][i] = 0;
        rep(i, 0, m) {
            int a, b, c;
            cin >> a >> b >> c;
            a--;
            b--;
            d[a][b] = c;
        }
        rep(k, 0, n) {
            rep(i, 0, n) {
                rep(j, 0, n) {
                    d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
                }
            }
        }
        int ans = 1e8;
        rep(i, 0, n) {
            ans = min(ans, d[s][i] + d[i][g1] + d[i][g2]);
        }
        cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 40
memory_kb: 3544
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;

bool solve() {
    int N, M, s, g1, g2;
    cin >> N >> M >> s >> g1 >> g2;
    if (!N) return false;

    vector<vector<pair<int, int>>> G1(N), G2(N);
    for (int _ = 0 ; _ < M ; _++) {
        int a, b, c; cin >> a >> b >> c;
        a--; b--;
        G1[a].emplace_back(b, c);
        G2[b].emplace_back(a, c);
    }
    
    auto dij = [&](vector<vector<pair<int, int>>> G, int st) -> vector<int> {
        const int inf = (int)1e9;
        vector<int> res(N, inf);
        res[st] = 0;
        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> que;
        que.push({ 0, st });
        while (que.size()) {
            auto [d, v] = que.top();
            que.pop();
            if (res[v] < d) continue;
            for (auto [x, w] : G[v]) {
                if (d + w < res[x]) {
                    res[x] = d + w;
                    que.push({ res[x], x });
                }
            }
        }
        return res;
    };

    vector<vector<int>> A(3, vector<int>{});
    A[0] = dij(G1, s - 1);
    A[1] = dij(G2, g1 - 1);
    A[2] = dij(G2, g2 - 1);
    assert(A[0].size() == (size_t)N);
    assert(A[1].size() == (size_t)N);
    assert(A[1].size() == (size_t)N);

    long long ans = (long long)1e18;
    for (int i = 0 ; i < N ; i++) {
        long long v = 0;
        for (int j = 0 ; j < 3 ; j++) v += A[j][i];
        ans = min(ans, v);
    }

    cout << ans << endl;

    return true;
}

int main() {
    while (solve()) ;
}
accuracy: 1
time_ms: 10
memory_kb: 3416
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n, m, s, g1, g2;
    while(cin >> n >> m >> s >> g1 >> g2, n){
        vector<vector<int>> A(n, vector<int>(n, 1 << 29));
        s--, g1--, g2--;
        int u, v, c;
        for(int i = 0; i < m; i++){
            cin >> u >> v >> c;
            u--, v--;
            A[u][v] = c;
        }
        for(int i = 0; i < n; i++)A[i][i] = 0;
        for(int k = 0; k < n; k++){
            for(int i = 0; i < n; i++){
                for(int j = 0; j < n; j++){
                    A[i][j] = min(A[i][j], A[i][k] + A[k][j]);
                }
            }
        }
        int ans = 1 << 30;
        for(int i = 0; i < n; i++){
            ans = min(ans, A[s][i] + A[i][g1] + A[i][g2]);
        }
        cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 30
memory_kb: 3448
final_rank: 6

code_snippet: #include<bits/stdc++.h>
#define int ll
#define rep(i, N) for(int i = 0; i < (int)(N); ++i)
#define rep1(i, N) for(int i = 1; i <= (int)(N); ++i)
#define per(i, N) for(int i = (N)-1; i >= 0; --i)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define bit(n, k) ((n) >> (k))
#define pcnt(n) (__builtin_popcount(n))
#define TakAo(ans) ans ? cout << "Takahashi\n" : cout << "Aoki\n"
#define YesNo(ans) ans ? cout << "Yes\n" : cout << "No\n"
#define endl '\n'
#define fi first
#define se second
#define mkpr make_pair
#define mktpl make_tuple
#define eb emplace_back

using namespace std;
using ll = int64_t;
using ull = uint64_t;
using ld = long double;
using point = struct{ ll x, y; };
using pointld = struct{ ld x, y; };
template<class T> using max_heap = priority_queue<T>;
template<class T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template<class T> using vec = vector<T>;
template<class T> using vvec = vec<vec<T>>;
template<class T> using vvvec = vec<vvec<T>>;
template<class T> using vvvvec = vvec<vvec<T>>;

constexpr ld EPS = 1e-10;
constexpr int INF = 1001001001;
constexpr ll LINF = 1001001001001001001ll;
constexpr ll MOD = (1) ? 998244353 : 1e9+7;
constexpr int NIL = -1;
constexpr int pm[2] = {1, -1};
constexpr int dy[8] = {0, 1, 1, 1, 0, -1, -1, -1};
constexpr int dx[8] = {1, 1, 0, -1, -1, -1, 0, 1};

ll cel(ll a, ll b){ return (a + b - 1) / b;}
ll Gcd(ll a, ll b){ return b ? Gcd(b, a % b) : abs(a);}
template<class T> T powi(T x, ll exp){
    return exp > 0 ? (exp & 1 ? x : 1) * powi(x * x, exp >> 1) : x / x;
}
ll modpow(ll x, ll exp, ll mod){
    x %= mod;
    return exp > 0 ? (exp & 1 ? x : 1) * modpow(x * x, exp >> 1, mod) % mod : 1;
}
template<class T> bool chmin(T &a, T b){ return a > b ? (a = b, true) : 0;}
template<class T> bool chmax(T &a, T b){ return a < b ? (a = b, true) : 0;}

using Pair = pair<ll, ll>;
using Tpl = tuple<char, int, int>;

class Warshall_Floyd{
    public:
    vector<vector<ll>> dist;
    int size;

    public:
    Warshall_Floyd(int N) : size(N), dist(N, vector<ll>(N, LINF)){
        for(int i = 0; i < N; i++) dist[i][i] = 0;
    }
    void add_edge(int u, int v, int w){
        dist[u][v] = w;
    }
    bool solve(){
        for(int k = 0; k < size; k++){
            for(int i = 0; i < size; i++){
                for(int j = 0; j < size; j++){
                    if(dist[i][k] == LINF || dist[k][j] == LINF) continue;
                    chmin(dist[i][j], dist[i][k] + dist[k][j]);
                }
            }
        }
        for(int i = 0; i < size; i++)
            if(dist[i][i] < 0) return false;
        return true;
    }
    int find_dist(int u, int v){
        return dist[u][v];
    }
    bool need_edge(int u, int v, int w){
        for(int i = 0; i < size; i++){
            if(i == u || i == v) continue;
            if(w >= dist[u][i] + dist[i][v]) return false;
        }
        return true;
    }
};

void Main(){
    while(1){
        int N, M, S, G1, G2; cin >> N >> M >> S >> G1 >> G2;
        if(N == 0) break;
        S--, G1--, G2--;

        Warshall_Floyd wf(N);
        vvec<int> G(N);
        rep(i, M){
            int a, b, c; cin >> a >> b >> c; a--, b--;
            G[a].eb(b);
            wf.add_edge(a, b, c);
        }

        wf.solve();
        
        ll ans = LINF;
        rep(i, N){
            ll val = wf.dist[S][i] + wf.dist[i][G1] + wf.dist[i][G2];
            chmin(ans, val);
        }

        cout << ans << endl;
    }
}
 
signed main(){
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(10);
    Main();
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3356
final_rank: 11

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll=long long;
const ll INF=1e8;
int main(void){
    ll n,m,x,y,z,q,w,e;
    while(cin>>n>>m>>x>>y>>z,n++){
        ll dp[n][n]={};
        for(ll i=0;i<n;i++){
            for(ll j=0;j<n;j++){
                if(i!=j){
                    dp[i][j]=INF;
                }
            }
        }
        for(ll i=0;i<m;i++){
            cin>>q>>w>>e;
            dp[q][w]=e;
        }
        for(ll k=0;k<n;k++){
            for(ll i=0;i<n;i++){
                for(ll j=0;j<n;j++){
                    dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]);
                }
            }
        }
        ll ans=INF;
        for(ll i=0;i<n;i++){
            ans=min(ans,dp[x][i]+dp[i][y]+dp[i][z]);
        }
        cout<<ans<<endl;
    }
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 3484
final_rank: 18

code_snippet: // I SELL YOU...! 
#include<iostream>
#include<vector>
#include<algorithm>
#include<functional>
#include<queue>
#include<chrono>
#include<iomanip>
#include<map>
#include<set>
using namespace std;
using ll = long long;
using P = pair<ll,ll>;
using TP = tuple<ll,ll,ll>;
void init_io(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(18);
}
const ll INF = 1e9;
void solve() {
  ll n,m,s,g1,g2;
  cin >> n >> m >> s >> g1 >> g2;
  if ((n|m|s|g1|g2) == 0) return;
  s--;
  g1--;
  g2--;
  vector<vector<ll>> d(n, vector<ll>(n, INF));
  for(int i=0;i<m;i++) {
    ll b1,b2,c;
    cin >> b1 >> b2 >> c;
    b1--;
    b2--;
    d[b1][b2] = c;
  }
  for (int i=0;i<n;i++) {
    d[i][i] = 0;
  }
  for (int k=0;k<n;k++) {
    for (int i=0;i<n;i++) {
      for (int j=0;j<n;j++) {
        d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
      }
    }
  }
  ll ans = INF;
  for (int i=0;i<n;i++) {
    ans = min(ans, d[s][i] + d[i][g1] + d[i][g2]);
  }
  cout << ans << endl;
  solve();
}
signed main(){
  init_io();
  solve();
}
accuracy: 1
time_ms: 30
memory_kb: 8384
final_rank: 20