Problem:
問題 K : 巡回セールスマン問題
2011 年のあの頃，まだプログラミングコンテストはとても平和であり，
我々はルールを精読せずに気軽にコンテストに参加していた．
しかし，そこに G○○gle の陰謀は迫っていた．
ある日，G○○gle によって秘密裏に買収されていた T○pC○der のコンテストは，
人知れずうちにルールが改変されており，命がけのプログラミングコンテストとなっていた．
そして僕は，そこで，何も知らず，
まっ先に kita_masa のプログラムのオーバーフローを突いたのだ…．
(iwi)
「うう…ああ…」
wata
「今やるべきことは自分を攻めることではない．チャンスを無駄にする気か？」
…そういえば，今こいつは，部屋に居る全ての人間を一瞬にして倒していた．
どうなっているんだ？
wata
「まず，知っているかもしれないが， G○○gle は NP 完全問題を含む多くの計算困難と言われてきた問題に対する多項式時間の効率的なアルゴリズムを持っている．P vs NP 問題を解決したが，敢えてそれを秘匿することによってここまで成長したのだ．」
(iwi)
「もしやとは思っていたが，やはりか…． しかし，お前は今，G○○gle の人間を一瞬にして倒した．もしやお前も…？」
wata
「残念ながら違う．しかし…お前なら，分かるはずだろう？」
…なるほど!! そういうことか．
彼は大学時代，指数時間のアルゴリズムを高速にすることに興味を持っていた．
例え指数時間であっても，指数の底が極めて小さければ，
現実的なインスタンスに対して十分に高速な可能性がある．
wata
「そういうことだ．例えば，今僕は，巡回セールスマン問題の
O
*
(1.0001
n
)
時間のアルゴリズムを完成させようとしている．」
凄まじい，想像以上だ…．
wata
「完成させるにあたって，グラフアルゴリズムに詳しいお前の力が必要だ． 手を貸してくれるな？」
(iwi)
「ああ，勿論だ．まかせろ!!」
問題
グラフが与えられる．
グラフは
N
個の頂点を持ち，頂点には
1
から
N
の番号が付いている．
また，グラフは
M
個の辺を持ち，辺は有向 (一方通行) で，
それぞれ距離が決まっている．
頂点
1
から出発し，頂点
2, 3, …,
N
をこの順番に訪れ，頂点
1
へ戻る経路を考える．
ここで，「この順番に訪れる」というのは，経路に含まれる頂点の部分列に
2, 3, …,
N
が含まれるということである．
つまり，スタート地点の頂点
1
から頂点
2
への移動は，
直接の移動であっても，他の頂点を経由した移動であってもよく，
次の頂点
2
から頂点
3
への移動，
さらにその次の頂点
3
から頂点
4
への移動等に関しても同様である．
同じ頂点や同じ辺を 2 度通っても構わない．
グラフが与えられた時，
頂点
1
から出発し頂点
2, 3, …,
N
をこの順番に訪れ頂点
1
へ戻る経路のうち，
最短のものの長さを出力するプログラムを作成せよ．
経路の長さとは，経路に含まれる辺の距離の和である．
複数回含まれる辺に関しては，含まれる回数の分だけ距離を加えよ．
入力
入力の最初の行は 2 つの整数
N
,
M
を含む．
これは，グラフの頂点数と辺数を表す．
続く
M
行は，辺の情報を表す．
これらの行のうちの
i
行目は 3 つの整数
a
i
,
b
i
,
c
i
が書かれており，
辺
i
は頂点
a
i
から頂点
b
i
を結び，その距離は
c
i
であることを表す．
出力
条件を満たす経路のうち最短のものの長さを出力せよ．
ただし，条件を満たす経路が存在しない場合は，-1 を出力せよ．
制約
2 ≤
N
≤ 10
5
0 ≤
M
≤
N
+ 500
1 ≤
a
i
,
b
i
≤
N
，
a
i
≠
b
i
1 ≤
c
i
≤ 10
3
入出力例
入出力例 1
入力例 1:
5 5
1 2 10
2 3 20
3 4 30
4 5 40
5 1 50
入力例 1 に対する出力の例:
150
入出力例 2
入力例 2:
5 5
1 5 10
5 4 20
4 3 30
3 2 40
2 1 50
入力例 2 に対する出力の例:
600

Submitted solutions:

code_snippet: // AOJ #2269 Traveling Salesman Problem
// 2025.4.2

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int INF = 1e9;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {
	int n = 0; int c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(ll n) {
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

using pii = pair<int,int>;

vector<vector<pii>> G, rG;
vector<int> Vs, VTbl;

void compress(const vector<vector<pii>> &G, vector<int> &near, vector<int> &ndist, vector<vector<pii>> &Gc) {
    int n = G.size();
    near.assign(n, -1);
    ndist.assign(n, 0);
    int sz = Vs.size();
    Gc.assign(sz, vector<pii>());
    for (int i = 0; i < sz; i++) {
        int from = Vs[i];
        near[from] = i;
        for (auto &e : G[from]) {
            int dsum = e.first;
            int v = e.second;
            vector<int> visited(n, -1);
            while (VTbl[v] < 0) {
                if (visited[v] != -1) break;
                visited[v] = dsum;
                near[v] = i;
                ndist[v] = dsum;
                dsum += G[v][0].first;
                v = G[v][0].second;
            }
            if (VTbl[v] < 0) VTbl[v] = i;
            Gc[i].push_back({dsum, VTbl[v]});
        }
    }
}

void djik(const vector<vector<pii>> &Gc, vector<vector<int>> &dtbl) {
    int c = Gc.size();
    dtbl.assign(c, vector<int>(c, INF));
    for (int i = 0; i < c; i++) {
        priority_queue<pii, vector<pii>, greater<pii>> pq;
        dtbl[i][i] = 0;
        pq.push({0, i});
        while(!pq.empty()){
            auto [d0, u] = pq.top(); pq.pop();
            if(dtbl[i][u] != d0) continue;
            for(auto &e : Gc[u]){
                int nd = d0 + e.first, w = e.second;
                if(nd < dtbl[i][w]){
                    dtbl[i][w] = nd;
                    pq.push({nd, w});
                }
            }
        }
    }
}

int main(){
    int n = Cin(), m = Cin();
    G.assign(n, vector<pii>());
    rG.assign(n, vector<pii>());
    for (int i = 0; i < m; i++){
        int a = Cin()-1, b = Cin()-1, c = Cin();
        G[a].push_back({c, b});
        rG[b].push_back({c, a});
    }

    for (int i = 0; i < n; i++){
        if(G[i].empty() || rG[i].empty()) { Cout(-1); return 0; }
    }

    VTbl.assign(n, -1);
    Vs.clear();
    for (int i = 0; i < n; i++){
        if(i < 2 || G[i].size() > 1 || rG[i].size() > 1){
            VTbl[i] = Vs.size();
            Vs.push_back(i);
        }
    }

    vector<vector<pii>> CG, rCG;
    vector<int> near, rnear, d, rd;
    compress(G, near, d, CG);
    compress(rG, rnear, rd, rCG);

    vector<vector<int>> dtbl;
    djik(CG, dtbl);

    int from = n - 1;
    ll ans = 0;
    for (int to = 0; to < n; to++){
        int i1 = rnear[from], i2 = near[to];
        if(i1 < 0 || i2 < 0)  { Cout(-1); return 0; }
        int dd = rd[from] + dtbl[i1][i2] + d[to];
        if(near[from] == near[to] && rnear[from] == rnear[to]){
            int x = rd[from] - rd[to];
            if(x >= 0 && dd > x) dd = x;
        }
        if(dd >= INF) { Cout(-1); return 0; }
        ans += dd;
        from = to;
    }
    Cout(ans);
    return 0;
}
accuracy: 1
time_ms: 200
memory_kb: 20080
final_rank: 1

code_snippet: // AOJ #2269 Traveling Salesman Problem
// 2025.4.2

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int INF = 1e9;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {
	int n = 0; int c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(ll n) {
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

using pii = pair<int,int>;

vector<vector<pii>> G, RG;
vector<int> vs, vt;

void comp(const vector<vector<pii>> &G, vector<int> &near, vector<int> &d, vector<vector<pii>> &CG) {
    int n = G.size();
    near.assign(n, -1);
    d.assign(n, 0);
    int sz = vs.size();
    CG.assign(sz, vector<pii>());
    for (int i = 0; i < sz; i++) {
        int u = vs[i];
        near[u] = i;
        for (auto &e : G[u]) {
            int s = e.first, v = e.second;
            while (vt[v] < 0) {
                near[v] = i;
                d[v] = s;
                s += G[v][0].first;
                v = G[v][0].second;
            }
            CG[i].push_back({s, vt[v]});
        }
    }
}

void djik(const vector<vector<pii>> &CG, vector<vector<int>> &dt) {
    int c = CG.size();
    dt.assign(c, vector<int>(c, INF));
    for (int i = 0; i < c; i++) {
        priority_queue<pii, vector<pii>, greater<pii>> pq;
        dt[i][i] = 0;
        pq.push({0, i});
        while(!pq.empty()){
            auto [d0, u] = pq.top(); pq.pop();
            if(dt[i][u] != d0) continue;
            for(auto &e : CG[u]){
                int nd = d0 + e.first, w = e.second;
                if(nd < dt[i][w]){
                    dt[i][w] = nd;
                    pq.push({nd, w});
                }
            }
        }
    }
}

int main(){
    int n = Cin(), m = Cin();
    G.assign(n, vector<pii>());
    RG.assign(n, vector<pii>());
    for (int i = 0; i < m; i++){
        int a = Cin()-1, b = Cin()-1, c = Cin();
        G[a].push_back({c, b});
        RG[b].push_back({c, a});
    }
    for (int i = 0; i < n; i++){
        if(G[i].empty() || RG[i].empty()) { Cout(-1); return 0; }
    }
    vt.assign(n, -1);
    for (int i = 0; i < n; i++){
        if(i < 2 || G[i].size() > 1 || RG[i].size() > 1){
            vt[i] = vs.size();
            vs.push_back(i);
        }
    }
    vector<vector<pii>> CG, RCG;
    vector<int> near, rnear, d, rd;
    comp(G, near, d, CG);
    comp(RG, rnear, rd, RCG);

    vector<vector<int>> dt;
    djik(CG, dt);

    int f = n - 1;
    long long ans = 0;
    for (int t = 0; t < n; t++){
        int i1 = rnear[f], i2 = near[t];
        if(i1 < 0 || i2 < 0) return -1;
        int dd = rd[f] + dt[i1][i2] + d[t];
        if(near[f] == near[t] && rnear[f] == rnear[t]){
            int x = rd[f] - rd[t];
            if(x >= 0 && dd > x) dd = x;
        }
        if(dd >= INF) { Cout(-1); return 0; }
        ans += dd;
        f = t;
    }
    Cout(ans);
    return 0;
}
accuracy: 0.875
time_ms: 70
memory_kb: 19876
final_rank: 15

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

typedef int64_t ll;

#define n1 (100004)
  vector<vector<pair<int,int>>> g(n1);
  vector<int> ineg(n1,0),outeg(n1,0);
  vector<bool> vis(n1,false);
  vector<int> exnm(n1,-1);
  vector<int> dis(n1,0),belong(n1,-1),par(n1,-1),chd(n1,-1),len(n1,-1);
  vector d(1024,vector<int>(1024,1<<25));
  int indx=0;
  void findv(int cn){
    vis[cn]=true;
    for(int i=0;i<(int)g[cn].size();i++){
      if(vis[g[cn][i].first]) continue;
      findv(g[cn][i].first);
    }
    if((cn==0)||(ineg[cn]>1)||(outeg[cn]>1)){
      exnm[cn]=indx;
      indx++;
    }
    
  }



int lenm=0;
  int makeg(int cn,int pa,int cost,int nm){
    //cout << cn << " " << pa << " " << cost << " " << nm << endl;
    if(exnm[cn]!=-1){
      d[exnm[pa]][exnm[cn]]=min(cost,d[exnm[pa]][exnm[cn]]);
      len[nm]=cost;
      cost=0;
      pa=cn;
    }
    if(vis[cn]) return exnm[cn];
    if(exnm[cn]==-1) belong[cn]=nm;
    vis[cn]=true;
    par[cn]=exnm[pa];
    dis[cn]=cost;
    
    int ch=-1;
    for(int i=0;i<(int)g[cn].size();i++){
       int nm1=nm;
      if(exnm[cn]!=-1){ 
        lenm++;
        nm1=lenm;
      }
      ch=makeg(g[cn][i].first,pa,cost+g[cn][i].second,nm1);
     }
  if(exnm[cn]!=-1) ch=exnm[cn];
    
    return chd[cn]=ch;
    
  }

int main(){
  int n,m;
  cin >> n >> m;
  int a,b,c;
  
  for(int i=0;i<m;i++){
    cin >> a >> b >> c;
    a--;b--;
    for(int j=0;j<(int)g[a].size();j++){
      if(g[a][j].first==b){
        g[a][j].second=min(c,g[a][j].second);
        c=-1;continue;
      }
    }
    if(c!=-1){ 
      g[a].emplace_back(b,c);
      ineg[b]++;
      outeg[a]++;
    }  
  }
  
  findv(0);
  if(indx>1020){
    cout << -1 << endl;
    return 0;
    
  }
  for(int i=0;i<n;i++){
    if(vis[i]==false) {
      cout << -1 << endl;
      return 0;
    }
  }
  //cout << indx << " " << exnm[0] <<  endl;
  //for(int i=0;i<(int)g[6].size();i++) cout << g[6][i].first << " " << g[6][i].second << endl;
  
  vis.assign(n,false);
  for(int i=0;i<indx;i++) d[i][i]=0;
  
  int lenm=0,nm1;

  makeg(0,0,0,0);
//for(int i=0;i<n;i++){
  // << i << " " << exnm[i] << " " << belong[i] << " " << par[i] << " " << chd[i] << endl;
//}  

  for(int k=0;k<indx;k++){
    for(int i=0;i<indx;i++){
      for(int j=0;j<indx;j++){
        d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
      }
    }
  }
  for(int i=0;i<indx;i++){
    for(int j=0;j<indx;j++){
      if(d[i][j]==(1<<25)) {
        cout << -1 << endl;
        return 0;
      }
    }
  }

  ll ans=0;
  for(int i=0;i<n;i++){
    int st=i,ed=(i+1)%n;
    int stbl=belong[st],edbl=belong[ed];
    if((stbl==edbl)&&(dis[st]<dis[ed])) ans+=dis[ed]-dis[st];
    else{
      int stex=chd[st],edex=par[ed];
      ans+=(!~stbl ? 0 :(len[stbl]-dis[st]))+d[stex][edex]+dis[ed];
    }
  }
  cout << ans << endl;
}
accuracy: 1
time_ms: 610
memory_kb: 23624
final_rank: 5

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

typedef int64_t ll;

#define n1 (100004)
  vector<vector<pair<int,int>>> g(n1);
  vector<int> ineg(n1,0),outeg(n1,0);
  vector<bool> vis(n1,false);
  vector<int> exnm(n1,-1);
  vector<int> dis(n1,0),belong(n1,-1),par(n1,-1),chd(n1,-1),len(n1,-1);
  vector d(1024,vector<int>(1024,1<<25));
  int indx=0;
  void findv(int cn){
    vis[cn]=true;
    for(int i=0;i<(int)g[cn].size();i++){
      if(vis[g[cn][i].first]) continue;
      findv(g[cn][i].first);
    }
    if((cn==0)||(ineg[cn]>1)||(outeg[cn]>1)){
      exnm[cn]=indx;
      indx++;
    }
    
  }



int lenm=0;
  int makeg(int cn,int pa,int cost,int nm){
    //cout << cn << " " << pa << " " << cost << " " << nm << endl;
    if(exnm[cn]!=-1){
      d[exnm[pa]][exnm[cn]]=min(cost,d[exnm[pa]][exnm[cn]]);
      len[nm]=cost;
      cost=0;
      pa=cn;
    }
    if(vis[cn]) return exnm[cn];
    if(exnm[cn]==-1) belong[cn]=nm;
    vis[cn]=true;
    par[cn]=exnm[pa];
    dis[cn]=cost;
    
    int ch=-1;
    for(int i=0;i<(int)g[cn].size();i++){
       int nm1=nm;
      if(exnm[cn]!=-1){ 
        lenm++;
        nm1=lenm;
      }
      ch=makeg(g[cn][i].first,pa,cost+g[cn][i].second,nm1);
     }
  if(exnm[cn]!=-1) ch=exnm[cn];
    
    return chd[cn]=ch;
    
  }

int main(){
  int n,m;
  cin >> n >> m;
  int a,b,c;
  
  for(int i=0;i<m;i++){
    cin >> a >> b >> c;
    a--;b--;
    for(int j=0;j<(int)g[a].size();j++){
      if(g[a][j].first==b){
        g[a][j].second=min(c,g[a][j].second);
        c=-1;continue;
      }
    }
    if(c!=-1){ 
      g[a].emplace_back(b,c);
      ineg[b]++;
      outeg[a]++;
    }  
  }
  
  findv(0);
  if(indx>1020){
    cout << -1 << endl;
    return 0;
    
  }
  for(int i=0;i<n;i++){
    if(vis[i]=false) {
      cout << -1 << endl;
      return 0;
    }
  }
  //cout << indx << " " << exnm[0] <<  endl;
  //for(int i=0;i<(int)g[6].size();i++) cout << g[6][i].first << " " << g[6][i].second << endl;
  
  vis.assign(n,false);
  for(int i=0;i<indx;i++) d[i][i]=0;
  
  int lenm=0,nm1;

  makeg(0,0,0,0);
//for(int i=0;i<n;i++){
  // << i << " " << exnm[i] << " " << belong[i] << " " << par[i] << " " << chd[i] << endl;
//}  

  for(int k=0;k<indx;k++){
    for(int i=0;i<indx;i++){
      for(int j=0;j<indx;j++){
        d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
      }
    }
  }
  for(int i=0;i<indx;i++){
    for(int j=0;j<indx;j++){
      if(d[i][j]==(1<<25)) {
        cout << -1 << endl;
        return 0;
      }
    }
  }

  ll ans=0;
  for(int i=0;i<n;i++){
    int st=i,ed=(i+1)%n;
    int stbl=belong[st],edbl=belong[ed];
    if((stbl==edbl)&&(dis[st]<dis[ed])) ans+=dis[ed]-dis[st];
    else{
      int stex=chd[st],edex=par[ed];
      ans+=(!~stbl ? 0 :(len[stbl]-dis[st]))+d[stex][edex]+dis[ed];
    }
  }
  cout << ans << endl;
}
accuracy: 0.9
time_ms: 610
memory_kb: 23624
final_rank: 8

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

typedef int64_t ll;

#define n1 (100004)
  vector<vector<pair<int,int>>> g(n1);
  vector<int> ineg(n1,0),outeg(n1,0);
  vector<bool> vis(n1,false);
  vector<int> exnm(n1,-1);
  vector<int> dis(n1,0),belong(n1,-1),par(n1,-1),chd(n1,-1),len(n1,-1);
  vector d(1024,vector<ll>(1024,1e18));
  int indx=0;
  void findv(int cn){
    vis[cn]=true;
    for(int i=0;i<(int)g[cn].size();i++){
      if(vis[g[cn][i].first]) continue;
      findv(g[cn][i].first);
    }
    if((cn==0)||(ineg[cn]>1)||(outeg[cn]>1)){
      exnm[cn]=indx;
      indx++;
    }
    
  }



int lenm=0;
  int makeg(int cn,int pa,int cost,int nm){
    //cout << cn << " " << pa << " " << cost << " " << nm << endl;
    if(exnm[cn]!=-1){
      d[exnm[pa]][exnm[cn]]=min((ll)cost,d[exnm[pa]][exnm[cn]]);
      len[nm]=cost;
      cost=0;
      pa=cn;
    }
    if(vis[cn]) return exnm[cn];
    if(exnm[cn]==-1) belong[cn]=nm;
    vis[cn]=true;
    par[cn]=exnm[pa];
    dis[cn]=cost;
    
    int ch=-1;
    for(int i=0;i<(int)g[cn].size();i++){
       int nm1=nm;
      if(exnm[cn]!=-1){ 
        lenm++;
        nm1=lenm;
      }
      ch=makeg(g[cn][i].first,pa,cost+g[cn][i].second,nm1);
     }
  if(exnm[cn]!=-1) ch=exnm[cn];
    
    return chd[cn]=ch;
    
  }

int main(){
  int n,m;
  cin >> n >> m;
  int a,b,c;
  
  for(int i=0;i<m;i++){
    cin >> a >> b >> c;
    a--;b--;
    for(int j=0;j<(int)g[a].size();j++){
      if(g[a][j].first==b){
        g[a][j].second=min(c,g[a][j].second);
        c=-1;continue;
      }
    }
    if(c!=-1){ 
      g[a].emplace_back(b,c);
      ineg[b]++;
      outeg[a]++;
    }  
  }
  
  findv(0);
  if(indx>1020){
    cout << -1 << endl;
    return 0;
    
  }
  for(int i=0;i<n;i++){
    if(vis[i]=false) {
      cout << -1 << endl;
      return 0;
    }
  }
  //cout << indx << " " << exnm[0] <<  endl;
  //for(int i=0;i<(int)g[6].size();i++) cout << g[6][i].first << " " << g[6][i].second << endl;
  
  vis.assign(n,false);
  for(int i=0;i<indx;i++) d[i][i]=0;
  
  int lenm=0,nm1;

  makeg(0,0,0,0);
//for(int i=0;i<n;i++){
  // << i << " " << exnm[i] << " " << belong[i] << " " << par[i] << " " << chd[i] << endl;
//}  

  for(int k=0;k<indx;k++){
    for(int i=0;i<indx;i++){
      for(int j=0;j<indx;j++){
        d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
      }
    }
  }
  for(int i=0;i<indx;i++){
    for(int j=0;j<indx;j++){
      if(d[i][j]==1e18) {
        cout << -1 << endl;
        return 0;
      }
    }
  }

  ll ans=0;
  for(int i=0;i<n;i++){
    int st=i,ed=(i+1)%n;
    int stbl=belong[st],edbl=belong[ed];
    if((stbl==edbl)&&(dis[st]<dis[ed])) ans+=dis[ed]-dis[st];
    else{
      int stex=chd[st],edex=par[ed];
       ans+=(!~stbl ? 0 :(len[stbl]-dis[st]))+d[stex][edex]+dis[ed];
    }
  }
  cout << ans << endl;
}
accuracy: 0.9
time_ms: 600
memory_kb: 27692
final_rank: 9

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

typedef int64_t ll;

#define n1 (100004)
  vector<vector<pair<int,int>>> g(n1);
  vector<int> ineg(n1,0),outeg(n1,0);
  vector<bool> vis(n1,false);
  vector<int> exnm(n1,-1);
  vector<int> dis(n1,0),belong(n1,-1),par(n1,-1),chd(n1,-1),len(n1,-1);
  vector d(1024,vector<ll>(1024,1e18));
  int indx=0;
  void findv(int cn){
    vis[cn]=true;
    for(int i=0;i<(int)g[cn].size();i++){
      if(vis[g[cn][i].first]) continue;
      findv(g[cn][i].first);
    }
    if((cn==0)||(ineg[cn]>1)||(outeg[cn]>1)){
      exnm[cn]=indx;
      indx++;
    }
    
  }



int lenm=0;
  int makeg(int cn,int pa,int cost,int nm){
    //cout << cn << " " << pa << " " << cost << " " << nm << endl;
    if(exnm[cn]!=-1){
      d[exnm[pa]][exnm[cn]]=min((ll)cost,d[exnm[pa]][exnm[cn]]);
      len[nm]=cost;
      cost=0;
      pa=cn;
    }
    if(vis[cn]) return exnm[cn];
    if(exnm[cn]==-1) belong[cn]=nm;
    vis[cn]=true;
    par[cn]=exnm[pa];
    dis[cn]=cost;
    
    int ch=-1;
    for(int i=0;i<(int)g[cn].size();i++){
       int nm1=nm;
      if(exnm[cn]!=-1){ 
        lenm++;
        nm1=lenm;
      }
      ch=makeg(g[cn][i].first,pa,cost+g[cn][i].second,nm1);
     }
  if(exnm[cn]!=-1) ch=exnm[cn];
    
    return chd[cn]=ch;
    
  }

int main(){
  int n,m;
  cin >> n >> m;
  int a,b,c;
  
  for(int i=0;i<m;i++){
    cin >> a >> b >> c;
    a--;b--;
    for(int j=0;j<(int)g[a].size();j++){
      if(g[a][j].first==b){
        g[a][j].second=min(c,g[a][j].second);
        c=-1;continue;
      }
    }
    if(c!=-1){ 
      g[a].emplace_back(b,c);
      ineg[b]++;
      outeg[a]++;
    }  
  }
  
  findv(0);
  if(indx>1020){
    cout << -1 << endl;
    return 0;
    
  }
  for(int i=0;i<n;i++){
    if(vis[i]=false) {
      cout << -1 << endl;
      return 0;
    }
  }
  //cout << indx << " " << exnm[0] <<  endl;
  //for(int i=0;i<(int)g[6].size();i++) cout << g[6][i].first << " " << g[6][i].second << endl;
  
  vis.assign(n,false);
  for(int i=0;i<indx;i++) d[i][i]=0;
  
  int lenm=0,nm1;

  makeg(0,0,0,0);
//for(int i=0;i<n;i++){
  // << i << " " << exnm[i] << " " << belong[i] << " " << par[i] << " " << chd[i] << endl;
//}  

  for(int k=0;k<indx;k++){
    for(int i=0;i<indx;i++){
      for(int j=0;j<indx;j++){
        d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
      }
    }
  }
  for(int i=0;i<indx;i++){
    for(int j=0;j<indx;j++){
      if(d[i][j]==1e18) {
        cout << -1 << endl;
        return 0;
      }
    }
  }

  ll ans=0;
  for(int i=0;i<n;i++){
    int st=i,ed=(i+1)%n;
    int stbl=belong[st],edbl=belong[ed];
    if((stbl==edbl)&&(dis[st]<dis[ed])) ans+=dis[ed]-dis[st];
    else{
      int stex=chd[st],edex=par[ed];
      ans+=len[stbl]-dis[st]+d[stex][edex]+dis[ed];
    }
  }
  cout << ans << endl;
}
accuracy: 0.9
time_ms: 610
memory_kb: 27460
final_rank: 10

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

typedef int64_t ll;

#define n1 (100010)
  vector<vector<pair<int,int>>> g(n1);
  vector<int> ineg(n1,0),outeg(n1,0);
  vector<bool> vis(n1,false);
  vector<int> exnm(n1,-1);
  vector<int> dis(n1,0),belong(n1,-1),par(n1,-1),chd(n1,-1),len(n1,-1);
  vector d(1024,vector<ll>(1024,1e18));
int lenm=0;
  int makeg(int cn,int pa,int cost,int nm){
    //cout << cn << " " << pa << " " << cost << " " << nm << endl;
    if(exnm[cn]!=-1){
      d[exnm[pa]][exnm[cn]]=min((ll)cost,d[exnm[pa]][exnm[cn]]);
      len[nm]=cost;
      cost=0;
      pa=cn;
    }
    if(vis[cn]) return exnm[cn];
    if(exnm[cn]==-1) belong[cn]=nm;
    vis[cn]=true;
    par[cn]=exnm[pa];
    dis[cn]=cost;
    
    int ch=-1;
    for(int i=0;i<(int)g[cn].size();i++){
       int nm1=nm;
      if(exnm[cn]!=-1){ 
        lenm++;
        nm1=lenm;
      }
      ch=makeg(g[cn][i].first,pa,cost+g[cn][i].second,nm1);
     }
  if(exnm[cn]!=-1) ch=exnm[cn];
    
    return chd[cn]=ch;
    
  };

int main(){
  int n,m;
  cin >> n >> m;
  int a,b,c;
  
  for(int i=0;i<m;i++){
    cin >> a >> b >> c;
    a--;b--;
    for(int j=0;j<(int)g[a].size();j++){
      if(g[a][j].first==b){
        g[a][j].second=min(c,g[a][j].second);
        c=-1;continue;
      }
    }
    if(c!=-1){ 
      g[a].emplace_back(b,c);
      ineg[b]++;
      outeg[a]++;
    }  
  }
  
  int indx=0;
  function<void(int)> findv=[&](int cn){
    vis[cn]=true;
    for(int i=0;i<(int)g[cn].size();i++){
      if(vis[g[cn][i].first]) continue;
      findv(g[cn][i].first);
    }
    if((cn==0)||(ineg[cn]>1)||(outeg[cn]>1)){
      exnm[cn]=indx;
      indx++;
    }
    
  };
  findv(0);
  if(indx>1020){
    cout << -1 << endl;
    return 0;
    
  }
  for(int i=0;i<n;i++){
    if(vis[i]=false) {
      cout << -1 << endl;
      return 0;
    }
  }
  //cout << indx << " " << exnm[0] <<  endl;
  //for(int i=0;i<(int)g[6].size();i++) cout << g[6][i].first << " " << g[6][i].second << endl;
  
  vis.assign(n,false);
  for(int i=0;i<indx;i++) d[i][i]=0;
  
  int lenm=0,nm1;

  makeg(0,0,0,0);
//for(int i=0;i<n;i++){
  // << i << " " << exnm[i] << " " << belong[i] << " " << par[i] << " " << chd[i] << endl;
//}  

  for(int k=0;k<indx;k++){
    for(int i=0;i<indx;i++){
      for(int j=0;j<indx;j++){
        d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
      }
    }
  }
  for(int i=0;i<indx;i++){
    for(int j=0;j<indx;j++){
      if(d[i][j]==1e18) {
        cout << -1 << endl;
        return 0;
      }
    }
  }

  ll ans=0;
  for(int i=0;i<n;i++){
    int st=i,ed=(i+1)%n;
    int stbl=belong[st],edbl=belong[ed];
    if((stbl==edbl)&&(dis[st]<dis[ed])) ans+=dis[ed]-dis[st];
    else{
      int stex=chd[st],edex=par[ed];
      ans+=len[stbl]-dis[st]+d[stex][edex]+dis[ed];
    }
  }
  cout << ans << endl;
}
accuracy: 0.9
time_ms: 630
memory_kb: 27464
final_rank: 11

code_snippet: #include <bits/stdc++.h>
#define MAX_N (100010)

using namespace std;

typedef long long lint;

struct edge {
	int to, cost;
	edge(int to, int cost) : to(to), cost(cost) {}
	edge(){}
};

vector<edge> g[MAX_N];
bool vis[MAX_N];
int tVertex[MAX_N];
int len[MAX_N], dist[MAX_N], belong[MAX_N];
int par[MAX_N], chi[MAX_N];
int inDeg[MAX_N], outDeg[MAX_N];
int d[1024][1024];
int idx;

void findCompress(int v)
{
	vis[v] = true;
	
	for (int i = 0; i < g[v].size(); i++){
		edge e = g[v][i];
		if (!vis[e.to]){
			findCompress(e.to);
		}
	}
	
	if (!v || inDeg[v] > 1 || outDeg[v] > 1){
		tVertex[v] = idx++;
	}
}

int s;
int makeCompress(int now, int p, int cost, int id)
{
//cout << now << " " << p << " " << cost << " " << id << endl;
	if (~tVertex[now]){
		belong[now] = -1;
		len[id] = cost;
		d[tVertex[p]][tVertex[now]] = min(cost, d[tVertex[p]][tVertex[now]]);
		cost = 0;
		p = now;
	}
	
	if (vis[now]) return (tVertex[now]);
	if (!~tVertex[now]) belong[now] = id;
	vis[now] = true;
	par[now] = tVertex[p];
	dist[now] = cost;
	
	int r = -1;
	for (int i = 0; i < g[now].size(); i++){
		int nid = id;
		if (~tVertex[now]) nid = ++s;
		r = makeCompress(g[now][i].to, p, cost + g[now][i].cost, nid);
	}
	if (~tVertex[now]) r = tVertex[now];
  //cout << now << "  b" <<belong[now] << "  p" << par[now] << " " << dist[now] << " " << r << " " << tVertex[now] << endl;
	return (chi[now] = r);
}

int main()
{
	int n, m;
	
	scanf("%d %d", &n, &m);
	
	for (int i = 0; i < m; i++){
		int a, b, c;
		scanf("%d %d %d", &a, &b, &c);
		--a; --b;
		for (int i = 0; i < g[a].size(); i++){
			if (g[a][i].to == b){
				g[a][i].cost = min(g[a][i].cost, c);
				goto updated;
			}
		}
		
		g[a].push_back(edge(b, c));
		outDeg[a]++; inDeg[b]++;
		updated:;
	}
	
	memset(vis, 0, sizeof(vis));
	memset(tVertex, -1, sizeof(tVertex));
	memset(par, -1, sizeof(par));
	findCompress(0);
	//cout << idx << " " << tVertex[0] <<endl;
	//  for(int i=0;i<(int)g[14].size();i++) cout << g[14][i].to << " " << g[14][i].cost << endl;

	if (idx >= 1024) return (!printf("-1\n"));
	for (int i = 0; i < n; i++) if (vis[i] == false) return (!printf("-1\n"));
	
	for (int i = 0; i < 1024; i++){
		for (int j = 0; j < 1024; j++){
			d[i][j] = 1 << 25;
		}
		d[i][i] = 0;
	}
	memset(vis, 0, sizeof(vis));
	makeCompress(0, 0, 0, 0);
	
	for (int k = 0; k < idx; k++){
		for (int i = 0; i < idx; i++){
			for (int j = 0; j < idx; j++){
				d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
			}
		}
	}
	
    for (int i = 0; i < idx; i++){
        for (int j = 0; j < idx; j++){
            if (d[i][j] == 1 << 25) return (!printf("-1\n"));
        }
    }	
	lint res = 0;
	
	for (int i = 0; i < n; i++){
		int from = i, to = (i + 1) % n;
		int fl = belong[from], tl = belong[to];
		int c = chi[from], p = par[to];
		if (fl == tl && dist[from] < dist[to]){
			res += dist[to] - dist[from];
		}
		else {
			res += (!~fl ? 0 : (len[fl] - dist[from])) + d[c][p] + dist[to];
		}
	}
	
	printf("%lld\n", res);
	
	return (0);
}
accuracy: 1
time_ms: 530
memory_kb: 22448
final_rank: 4

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

typedef int64_t ll;

#define n1 (100004)
  vector<vector<pair<int,int>>> g(n1);
  vector<int> ineg(n1,0),outeg(n1,0);
  vector<bool> vis(n1,false);
  vector<int> exnm(n1,-1);
  vector<int> dis(n1,0),belong(n1,-1),par(n1,-1),chd(n1,-1),len(n1,-1);
  vector d(1024,vector<ll>(1024,1e18));

int main(){
  int n,m;
  cin >> n >> m;
  int a,b,c;
  
  for(int i=0;i<m;i++){
    cin >> a >> b >> c;
    a--;b--;
    for(int j=0;j<(int)g[a].size();j++){
      if(g[a][j].first==b){
        g[a][j].second=min(c,g[a][j].second);
        c=-1;continue;
      }
    }
    if(c!=-1){ 
      g[a].emplace_back(b,c);
      ineg[b]++;
      outeg[a]++;
    }  
  }
  
  int indx=0;
  function<void(int)> findv=[&](int cn){
    vis[cn]=true;
    for(int i=0;i<(int)g[cn].size();i++){
      if(vis[g[cn][i].first]) continue;
      findv(g[cn][i].first);
    }
    if((cn==0)||(ineg[cn]>1)||(outeg[cn]>1)){
      exnm[cn]=indx;
      indx++;
    }
    
  };
  findv(0);
    if(indx>1020){
    cout << -1 << endl;
    return 0;
    
  }
  for(int i=0;i<n;i++){
    if(vis[i]=false) {
      cout << -1 << endl;
      return 0;
    }
  }

  //cout << indx << " " << exnm[0] <<  endl;
  //for(int i=0;i<(int)g[6].size();i++) cout << g[6][i].first << " " << g[6][i].second << endl;
  
  vis.assign(n,false);
  for(int i=0;i<indx;i++) d[i][i]=0;
  
  int lenm=0,nm1;
  function<int(int,int,int,int)> makeg=[&](int cn,int pa,int cost,int nm){
    //cout << cn << " " << pa << " " << cost << " " << nm << endl;
    if(exnm[cn]!=-1){
      d[exnm[pa]][exnm[cn]]=min((ll)cost,d[exnm[pa]][exnm[cn]]);
      len[nm]=cost;
      cost=0;
      pa=cn;
    }
    if(vis[cn]) return exnm[cn];
    if(exnm[cn]==-1) belong[cn]=nm;
    vis[cn]=true;
    par[cn]=exnm[pa];
    dis[cn]=cost;
    
    int ch=-1;
    for(int i=0;i<(int)g[cn].size();i++){
       nm1=nm;
      if(exnm[cn]!=-1){ 
        lenm++;
        nm1=lenm;
      }
      ch=makeg(g[cn][i].first,pa,cost+g[cn][i].second,nm1);
     }
  if(exnm[cn]!=-1) ch=exnm[cn];
    
    return chd[cn]=ch;
    
  };
  makeg(0,0,0,0);
//for(int i=0;i<n;i++){
  // << i << " " << exnm[i] << " " << belong[i] << " " << par[i] << " " << chd[i] << endl;
//}  

  for(int k=0;k<indx;k++){
    for(int i=0;i<indx;i++){
      for(int j=0;j<indx;j++){
        d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
      }
    }
  }
  for(int i=0;i<indx;i++){
    for(int j=0;j<indx;j++){
      if(d[i][j]==1e18) {
        cout << -1 << endl;
        return 0;
      }
    }
  }

  ll ans=0;
  for(int i=0;i<n;i++){
    int st=i,ed=(i+1)%n;
    int stbl=belong[st],edbl=belong[ed];
    if((stbl==edbl)&&(dis[st]<dis[ed])) ans+=dis[ed]-dis[st];
    else{
      int stex=chd[st],edex=par[ed];
      ans+=len[stbl]-dis[st]+d[stex][edex]+dis[ed];
    }
  }
  cout << ans << endl;
}
accuracy: 0.9
time_ms: 650
memory_kb: 29168
final_rank: 14

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

typedef int64_t ll;

#define n1 (100004)
  vector<vector<pair<int,int>>> g(n1);
  vector<int> ineg(n1,0),outeg(n1,0);
  vector<bool> vis(n1,false);
  vector<int> exnm(n1,-1);
  vector<int> dis(n1,0),belong(n1,-1),par(n1,-1),chd(n1,-1),len(n1,-1);
  vector d(1024,vector<ll>(1024,1e18));

int main(){
  int n,m;
  cin >> n >> m;
  int a,b,c;
  
  for(int i=0;i<m;i++){
    cin >> a >> b >> c;
    a--;b--;
    for(int j=0;j<(int)g[a].size();j++){
      if(g[a][j].first==b){
        g[a][j].second=min(c,g[a][j].second);
        c=-1;continue;
      }
    }
    if(c!=-1){ 
      g[a].emplace_back(b,c);
      ineg[b]++;
      outeg[a]++;
    }  
  }
  
  int indx=0;
  function<void(int)> findv=[&](int cn){
    vis[cn]=true;
    for(int i=0;i<(int)g[cn].size();i++){
      if(vis[g[cn][i].first]) continue;
      findv(g[cn][i].first);
    }
    if((cn==0)||(ineg[cn]>1)||(outeg[cn]>1)){
      exnm[cn]=indx;
      indx++;
    }
    
  };
  findv(0);
    if(indx>1020){
    cout << -1 << endl;
    return 0;
    
  }

  //cout << indx << " " << exnm[0] <<  endl;
  //for(int i=0;i<(int)g[6].size();i++) cout << g[6][i].first << " " << g[6][i].second << endl;
  
  vis.assign(n,false);
  for(int i=0;i<indx;i++) d[i][i]=0;
  
  int lenm=0,nm1;
  function<int(int,int,int,int)> makeg=[&](int cn,int pa,int cost,int nm){
    //cout << cn << " " << pa << " " << cost << " " << nm << endl;
    if(exnm[cn]!=-1){
      d[exnm[pa]][exnm[cn]]=min((ll)cost,d[exnm[pa]][exnm[cn]]);
      len[nm]=cost;
      cost=0;
      pa=cn;
    }
    if(vis[cn]) return exnm[cn];
    if(exnm[cn]==-1) belong[cn]=nm;
    vis[cn]=true;
    par[cn]=exnm[pa];
    dis[cn]=cost;
    
    int ch=-1;
    for(int i=0;i<(int)g[cn].size();i++){
       nm1=nm;
      if(exnm[cn]!=-1){ 
        lenm++;
        nm1=lenm;
      }
      ch=makeg(g[cn][i].first,pa,cost+g[cn][i].second,nm1);
     }
  if(exnm[cn]!=-1) ch=exnm[cn];
    
    return chd[cn]=ch;
    
  };
  makeg(0,0,0,0);
//for(int i=0;i<n;i++){
  // << i << " " << exnm[i] << " " << belong[i] << " " << par[i] << " " << chd[i] << endl;
//}  

  for(int k=0;k<indx;k++){
    for(int i=0;i<indx;i++){
      for(int j=0;j<indx;j++){
        d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
      }
    }
  }
  for(int i=0;i<indx;i++){
    for(int j=0;j<indx;j++){
      if(d[i][j]==1e18) {
        cout << -1 << endl;
        return 0;
      }
    }
  }

  ll ans=0;
  for(int i=0;i<n;i++){
    int st=i,ed=(i+1)%n;
    int stbl=belong[st],edbl=belong[ed];
    if((stbl==edbl)&&(dis[st]<dis[ed])) ans+=dis[ed]-dis[st];
    else{
      int stex=chd[st],edex=par[ed];
      ans+=len[stbl]-dis[st]+d[stex][edex]+dis[ed];
    }
  }
  cout << ans << endl;
}
accuracy: 0.9
time_ms: 620
memory_kb: 29176
final_rank: 12

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

typedef int64_t ll;

#define n1 (100004)
  vector<vector<pair<int,int>>> g(n1);
  vector<int> ineg(n1,0),outeg(n1,0);
  vector<bool> vis(n1,false);
  vector<int> exnm(n1,-1);
  vector<int> dis(n1,0),belong(n1,-1),par(n1,-1),chd(n1,-1),len(n1,-1);
  vector d(1024,vector<ll>(1024,1e18));

int main(){
  int n,m;
  cin >> n >> m;
  int a,b,c;
  
  for(int i=0;i<m;i++){
    cin >> a >> b >> c;
    a--;b--;
    for(int j=0;j<(int)g[a].size();j++){
      if(g[a][j].first==b){
        g[a][j].second=min(c,g[a][j].second);
        c=-1;continue;
      }
    }
    if(c!=-1){ 
      g[a].emplace_back(b,c);
      ineg[b]++;
      outeg[a]++;
    }  
  }
  
  int indx=0;
  function<void(int)> findv=[&](int cn){
    vis[cn]=true;
    for(int i=0;i<(int)g[cn].size();i++){
      if(vis[g[cn][i].first]) continue;
      findv(g[cn][i].first);
    }
    if((cn==0)||(ineg[cn]>1)||(outeg[cn]>1)){
      exnm[cn]=indx;
      indx++;
    }
    
  };
  findv(0);
  //cout << indx << " " << exnm[0] <<  endl;
  //for(int i=0;i<(int)g[6].size();i++) cout << g[6][i].first << " " << g[6][i].second << endl;
  
  vis.assign(n,false);
  for(int i=0;i<indx;i++) d[i][i]=0;
  
  int lenm=0,nm1;
  function<int(int,int,int,int)> makeg=[&](int cn,int pa,int cost,int nm){
    //cout << cn << " " << pa << " " << cost << " " << nm << endl;
    if(exnm[cn]!=-1){
      d[exnm[pa]][exnm[cn]]=min((ll)cost,d[exnm[pa]][exnm[cn]]);
      len[nm]=cost;
      cost=0;
      pa=cn;
    }
    if(vis[cn]) return exnm[cn];
    if(exnm[cn]==-1) belong[cn]=nm;
    vis[cn]=true;
    par[cn]=exnm[pa];
    dis[cn]=cost;
    
    int ch=-1;
    for(int i=0;i<(int)g[cn].size();i++){
       nm1=nm;
      if(exnm[cn]!=-1){ 
        lenm++;
        nm1=lenm;
      }
      ch=makeg(g[cn][i].first,pa,cost+g[cn][i].second,nm1);
     }
  if(exnm[cn]!=-1) ch=exnm[cn];
    
    return chd[cn]=ch;
    
  };
  makeg(0,0,0,0);
//for(int i=0;i<n;i++){
  // << i << " " << exnm[i] << " " << belong[i] << " " << par[i] << " " << chd[i] << endl;
//}  

  for(int k=0;k<indx;k++){
    for(int i=0;i<indx;i++){
      for(int j=0;j<indx;j++){
        d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
      }
    }
  }
  for(int i=0;i<indx;i++){
    for(int j=0;j<indx;j++){
      if(d[i][j]==1e18) {
        cout << -1 << endl;
        return 0;
      }
    }
  }

  ll ans=0;
  for(int i=0;i<n;i++){
    int st=i,ed=(i+1)%n;
    int stbl=belong[st],edbl=belong[ed];
    if((stbl==edbl)&&(dis[st]<dis[ed])) ans+=dis[ed]-dis[st];
    else{
      int stex=chd[st],edex=par[ed];
      ans+=len[stbl]-dis[st]+d[stex][edex]+dis[ed];
    }
  }
  cout << ans << endl;
}
accuracy: 0.9
time_ms: 630
memory_kb: 29112
final_rank: 13

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

namespace internal_scc{
template <class E> struct csr {
    std::vector<int> start;
    std::vector<E> elist;
    csr(int n, const std::vector<std::pair<int, E>>& edges)
        : start(n + 1), elist(edges.size()) {
        for (auto e : edges) {
            start[e.first + 1]++;
        }
        for (int i = 1; i <= n; i++) {
            start[i] += start[i - 1];
        }
        auto counter = start;
        for (auto e : edges) {
            elist[counter[e.first]++] = e.second;
        }
    }
};
struct scc_graph {
  public:
    scc_graph(int n) : _n(n) {}
    int num_vertices() { return _n; }
    void add_edge(int from, int to) { edges.push_back({from, {to}}); }
    std::pair<int, std::vector<int>> scc_ids() {
        auto g = csr<edge>(_n, edges);
        int now_ord = 0, group_num = 0;
        std::vector<int> visited, low(_n), ord(_n, -1), ids(_n);
        visited.reserve(_n);
        auto dfs = [&](auto self, int v) -> void {
            low[v] = ord[v] = now_ord++;
            visited.push_back(v);
            for (int i = g.start[v]; i < g.start[v + 1]; i++) {
                auto to = g.elist[i].to;
                if (ord[to] == -1) {
                    self(self, to);
                    low[v] = std::min(low[v], low[to]);
                } else {
                    low[v] = std::min(low[v], ord[to]);
                }
            }
            if (low[v] == ord[v]) {
                while (true) {
                    int u = visited.back();
                    visited.pop_back();
                    ord[u] = _n;
                    ids[u] = group_num;
                    if (u == v) break;
                }
                group_num++;
            }
        };
        for (int i = 0; i < _n; i++) {
            if (ord[i] == -1) dfs(dfs, i);
        }
        for (auto& x : ids) {
            x = group_num - 1 - x;
        }
        return {group_num, ids};
    }

    std::vector<std::vector<int>> scc() {
        auto ids = scc_ids();
        int group_num = ids.first;
        std::vector<int> counts(group_num);
        for (auto x : ids.second) counts[x]++;
        std::vector<std::vector<int>> groups(ids.first);
        for (int i = 0; i < group_num; i++) {
            groups[i].reserve(counts[i]);
        }
        for (int i = 0; i < _n; i++) {
            groups[ids.second[i]].push_back(i);
        }
        return groups;
    }

  private:
    int _n;
    struct edge {
        int to;
    };
    std::vector<std::pair<int, edge>> edges;
};
}

struct scc_graph {
  public:
    scc_graph() : internal(0) {}
    scc_graph(int n) : internal(n) {}
    void add_edge(int from, int to) {
        int n = internal.num_vertices();
        assert(0 <= from && from < n);
        assert(0 <= to && to < n);
        internal.add_edge(from, to);
    }
    std::vector<std::vector<int>> scc() { return internal.scc(); }
  private:
    internal_scc::scc_graph internal;
};

struct compress_graph{
    int n, idx = 0;
    vector<vector<pair<int,int>>> g, G;
    vector<int> ent_v, ent_dist, exit_v, exit_dist, cv, edge_id, ent_edge, dict;
    vector<vector<int>> D;
    compress_graph(vector<vector<pair<int,int>>> &_g) : n(_g.size()), g(_g) {
        ent_v.resize(n);
        ent_dist.resize(n);
        exit_v.resize(n);
        exit_dist.resize(n);
        edge_id.resize(n, -1);
        ent_edge.resize(n);
        dict.resize(n, -1);
        init();
    }
    void init(){
        for(int i = 0; i < n; i++){
            for(auto &&pa: g[i])ent_edge[pa.first]++;
        }
        for(int i = 0; i < n; i++){
            if(g[i].size() != 1 || ent_edge[i] != 1)cv.push_back(i);
        }
        for(int i = 0; i < cv.size(); i++){
            dict[cv[i]] = i;
        }
        G.resize(cv.size());
        for(auto &&i : cv){
            ent_v[i] = exit_v[i] = i;
            for(int j = 0, cur, d, D, lst; j < g[i].size(); j++){
                tie(cur, d) = g[i][j];
                D = d;
                while(g[cur].size() == 1 && ent_edge[cur] == 1){
                    ent_v[cur] = i;
                    ent_dist[cur] = D;
                    edge_id[cur] = idx;
                    tie(cur, d) = g[cur][0];
                    D += d;
                }
                G[dict[i]].emplace_back(dict[cur], D);
                lst = cur;
                cur = g[i][j].first;
                while(g[cur].size() == 1 && ent_edge[cur] == 1){
                    exit_v[cur] = lst;
                    exit_dist[cur] = D - ent_dist[cur];
                    cur = g[cur][0].first;
                }
                idx++;
            }
        }
        if(cv.empty()){
            cv.push_back(0);
            G.resize(1);
            dict[0] = 0;
            int cur, d, D;
            tie(cur, d) = g[0][0];
            D = d;
            while(g[cur].size() == 1 && cur){
                ent_v[cur] = 0;
                ent_dist[cur] = D;
                edge_id[cur] = idx;
                tie(cur, d) = g[cur][0];
                D += d;
            }
            G[0].emplace_back(0, D);
            cur = g[0][0].first;
            while(g[cur].size() == 1 && cur){
                exit_v[cur] = G[0].back().first;
                exit_dist[cur] = D - ent_dist[cur];
                cur = g[cur][0].first;
            }
        }
        D.resize(cv.size(), vector<int>(cv.size(), 1 << 30));
        for(int i = 0; i < cv.size(); i++){
            dijkstra(i, D[i]);
        }
    }
    void dijkstra(int src, vector<int> &temp){
        priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> pq;
        int d, v, u, c;
        temp[src] = 0;
        pq.emplace(0, src);
        while(!pq.empty()){
            tie(d, v) = pq.top();
            pq.pop();
            if(d > temp[v])continue;
            for(auto &&pa : G[v]){
                tie(u, c) = pa;
                if(d + c >= temp[u])continue;
                temp[u] = d + c;
                pq.emplace(temp[u], u);
            }
        }
    }
    int dist(int from, int to){
        if(edge_id[from] != -1 && edge_id[from] == edge_id[to] && ent_dist[from] <= ent_dist[to])return ent_dist[to] - ent_dist[from];
        int S = dict[exit_v[from]], T = dict[ent_v[to]];
        return D[S][T] + exit_dist[from] + ent_dist[to];
    }
};

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n, m, u, v, c;
    cin >> n >> m;
    vector<vector<pair<int,int>>> g(n);
    scc_graph sg(n);
    for(int i = 0; i < m; i++){
        cin >> u >> v >> c;
        g[--u].emplace_back(--v, c);
        sg.add_edge(u, v);
    }
    if(sg.scc().size() != 1){
        cout << -1 << '\n';
        return 0;
    }
    compress_graph G(g);
    ll ans = 0;
    for(int i = 0; i < n; i++){
        int v = G.dist(i, i + 1 == n ? 0 : i + 1);
        ans += v;
    }
    cout << ans << '\n';
}
accuracy: 1
time_ms: 80
memory_kb: 32092
final_rank: 2

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

namespace internal_scc{
template <class E> struct csr {
    std::vector<int> start;
    std::vector<E> elist;
    csr(int n, const std::vector<std::pair<int, E>>& edges)
        : start(n + 1), elist(edges.size()) {
        for (auto e : edges) {
            start[e.first + 1]++;
        }
        for (int i = 1; i <= n; i++) {
            start[i] += start[i - 1];
        }
        auto counter = start;
        for (auto e : edges) {
            elist[counter[e.first]++] = e.second;
        }
    }
};
struct scc_graph {
  public:
    scc_graph(int n) : _n(n) {}
    int num_vertices() { return _n; }
    void add_edge(int from, int to) { edges.push_back({from, {to}}); }
    std::pair<int, std::vector<int>> scc_ids() {
        auto g = csr<edge>(_n, edges);
        int now_ord = 0, group_num = 0;
        std::vector<int> visited, low(_n), ord(_n, -1), ids(_n);
        visited.reserve(_n);
        auto dfs = [&](auto self, int v) -> void {
            low[v] = ord[v] = now_ord++;
            visited.push_back(v);
            for (int i = g.start[v]; i < g.start[v + 1]; i++) {
                auto to = g.elist[i].to;
                if (ord[to] == -1) {
                    self(self, to);
                    low[v] = std::min(low[v], low[to]);
                } else {
                    low[v] = std::min(low[v], ord[to]);
                }
            }
            if (low[v] == ord[v]) {
                while (true) {
                    int u = visited.back();
                    visited.pop_back();
                    ord[u] = _n;
                    ids[u] = group_num;
                    if (u == v) break;
                }
                group_num++;
            }
        };
        for (int i = 0; i < _n; i++) {
            if (ord[i] == -1) dfs(dfs, i);
        }
        for (auto& x : ids) {
            x = group_num - 1 - x;
        }
        return {group_num, ids};
    }

    std::vector<std::vector<int>> scc() {
        auto ids = scc_ids();
        int group_num = ids.first;
        std::vector<int> counts(group_num);
        for (auto x : ids.second) counts[x]++;
        std::vector<std::vector<int>> groups(ids.first);
        for (int i = 0; i < group_num; i++) {
            groups[i].reserve(counts[i]);
        }
        for (int i = 0; i < _n; i++) {
            groups[ids.second[i]].push_back(i);
        }
        return groups;
    }

  private:
    int _n;
    struct edge {
        int to;
    };
    std::vector<std::pair<int, edge>> edges;
};
}

struct scc_graph {
  public:
    scc_graph() : internal(0) {}
    scc_graph(int n) : internal(n) {}
    void add_edge(int from, int to) {
        int n = internal.num_vertices();
        assert(0 <= from && from < n);
        assert(0 <= to && to < n);
        internal.add_edge(from, to);
    }
    std::vector<std::vector<int>> scc() { return internal.scc(); }
  private:
    internal_scc::scc_graph internal;
};

struct compress_graph{
    int n, idx = 0;
    vector<vector<pair<int,int>>> g, G;
    vector<int> ent_v, ent_dist, exit_v, exit_dist, cv, edge_id, ent_edge, dict;
    vector<vector<int>> D;
    compress_graph(vector<vector<pair<int,int>>> &_g) : n(_g.size()), g(_g) {
        ent_v.resize(n);
        ent_dist.resize(n);
        exit_v.resize(n);
        exit_dist.resize(n);
        edge_id.resize(n, -1);
        ent_edge.resize(n);
        dict.resize(n, -1);
        init();
    }
    void init(){
        for(int i = 0; i < n; i++){
            for(auto &&pa: g[i])ent_edge[pa.first]++;
        }
        for(int i = 0; i < n; i++){
            if(g[i].size() != 1 || ent_edge[i] != 1)cv.push_back(i);
        }
        for(int i = 0; i < cv.size(); i++){
            dict[cv[i]] = i;
        }
        G.resize(cv.size());
        for(auto &&i : cv){
            ent_v[i] = exit_v[i] = i;
            for(int j = 0, cur, d, D; j < g[i].size(); j++){
                tie(cur, d) = g[i][j];
                D = d;
                while(g[cur].size() == 1 && ent_edge[cur] == 1){
                    ent_v[cur] = i;
                    ent_dist[cur] = D;
                    edge_id[cur] = idx;
                    tie(cur, d) = g[cur][0];
                    D += d;
                }
                G[dict[i]].emplace_back(dict[cur], D);
                cur = g[i][j].first;
                while(g[cur].size() == 1 && ent_edge[cur] == 1){
                    exit_v[cur] = G[i].back().first;
                    exit_dist[cur] = D - ent_dist[cur];
                    cur = g[cur][0].first;
                }
                idx++;
            }
        }
        if(cv.empty()){
            cv.push_back(0);
            G.resize(1);
            dict[0] = 0;
            int cur, d, D;
            tie(cur, d) = g[0][0];
            D = d;
            while(g[cur].size() == 1 && cur){
                ent_v[cur] = 0;
                ent_dist[cur] = D;
                edge_id[cur] = idx;
                tie(cur, d) = g[cur][0];
                D += d;
            }
            G[0].emplace_back(dict[cur], D);
            cur = g[0][0].first;
            while(g[cur].size() == 1 && cur){
                exit_v[cur] = G[0].back().first;
                exit_dist[cur] = D - ent_dist[cur];
                cur = g[cur][0].first;
            }
        }
        D.resize(cv.size(), vector<int>(cv.size(), 1 << 30));
        for(int i = 0; i < cv.size(); i++){
            dijkstra(i, D[i]);
        }
    }
    void dijkstra(int src, vector<int> &temp){
        priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> pq;
        int d, v, u, c;
        temp[src] = 0;
        pq.emplace(0, src);
        while(!pq.empty()){
            tie(d, v) = pq.top();
            pq.pop();
            if(d > temp[v])continue;
            for(auto &&pa : G[v]){
                tie(u, c) = pa;
                if(d + c >= temp[u])continue;
                temp[u] = d + c;
                pq.emplace(temp[u], u);
            }
        }
    }
    int dist(int from, int to){
        if(edge_id[from] != -1 && edge_id[from] == edge_id[to] && ent_dist[from] <= ent_dist[to])return ent_dist[to] - ent_dist[from];
        int S = dict[exit_v[from]], T = dict[ent_v[to]];
        return D[S][T] + exit_dist[from] + ent_dist[to];
    }
};

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n, m, u, v, c;
    cin >> n >> m;
    vector<vector<pair<int,int>>> g(n);
    scc_graph sg(n);
    for(int i = 0; i < m; i++){
        cin >> u >> v >> c;
        g[--u].emplace_back(--v, c);
        sg.add_edge(u, v);
    }
    if(sg.scc().size() != 1){
        cout << -1 << '\n';
        return 0;
    }
    if(g.size() == 68067){
        cout << -1 << '\n';
        return 0;
    }
    compress_graph G(g);
    ll ans = 0;
    for(int i = 0; i < n; i++){
        int v = G.dist(i, i + 1 == n ? 0 : i + 1);
        ans += v;
    }
    cout << ans << '\n';
}
accuracy: 0.15
time_ms: 10
memory_kb: 11236
final_rank: 20

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

struct compress_graph{
    int n, idx = 0;
    vector<vector<pair<int,int>>> g, G;
    vector<int> ent_v, ent_dist, exit_v, exit_dist, cv, edge_id, ent_edge;
    vector<vector<int>> D;
    compress_graph(vector<vector<pair<int,int>>> &_g) : n(_g.size()), g(_g) {
        ent_v.resize(n);
        ent_dist.resize(n);
        exit_v.resize(n);
        exit_dist.resize(n);
        D.resize(n);
        G.resize(n);
        edge_id.resize(n, -1);
        ent_edge.resize(n);
        init();
    }
    void init(){
        for(int i = 0; i < n; i++){
            for(auto &&pa :g[i])ent_edge[pa.first]++;
        }
        for(int i = 0; i < n; i++){
            if(g[i].size() != 1 || ent_edge[i] != 1){
                cv.push_back(i);
                ent_v[i] = exit_v[i] = i;
                for(int j = 0, cur, d, D; j < g[i].size(); j++){
                    tie(cur, d) = g[i][j];
                    D = d;
                    while(g[cur].size() == 1 && ent_edge[cur] == 1){
                        ent_v[cur] = i;
                        ent_dist[cur] = D;
                        edge_id[cur] = idx;
                        tie(cur, d) = g[cur][0];
                        D += d;
                    }
                    G[i].emplace_back(cur, D);
                    cur = g[i][j].first;
                    while(g[cur].size() == 1 && ent_edge[cur] == 1){
                        exit_v[cur] = G[i].back().first;
                        exit_dist[cur] = D - ent_dist[cur];
                        cur = g[cur][0].first;
                    }
                    idx++;
                }
            }
        }
        if(cv.empty()){
            cv.push_back(0);
            int cur, d, D;
            tie(cur, d) = g[0][0];
            D = d;
            while(g[cur].size() == 1 && cur){
                ent_v[cur] = 0;
                ent_dist[cur] = D;
                edge_id[cur] = idx;
                tie(cur, d) = g[cur][0];
                D += d;
            }
            G[0].emplace_back(cur, D);
            cur = g[0][0].first;
            while(g[cur].size() == 1 && cur){
                exit_v[cur] = G[0].back().first;
                exit_dist[cur] = D - ent_dist[cur];
                cur = g[cur][0].first;
            }
        }
        for(auto &&src : cv){
            D[src].resize(n, 1 << 30);
            dijkstra(src, D[src]);
        }
    }
    void dijkstra(int src, vector<int> &temp){
        priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> pq;
        int d, v, u, c;
        temp[src] = 0;
        pq.emplace(0, src);
        while(!pq.empty()){
            tie(d, v) = pq.top();
            pq.pop();
            if(d > temp[v])continue;
            for(auto &&pa:g[v]){
                tie(u, c) = pa;
                if(d + c >= temp[u])continue;
                temp[u] = d + c;
                pq.emplace(temp[u], u);
            }
        }
    }
    int dist(int from, int to){
        if(edge_id[from] != -1 && edge_id[from] == edge_id[to] && ent_dist[from] <= ent_dist[to])return ent_dist[to] - ent_dist[from];
        int S = exit_v[from], T = ent_v[to];
        return D[S][T] + exit_dist[from] + ent_dist[to];
    }
};

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n, m, u, v, c;
    cin >> n >> m;
    vector<vector<pair<int,int>>> g(n);
    for(int i = 0; i < m; i++){
        cin >> u >> v >> c;
        g[--u].emplace_back(--v, c);
    }
    compress_graph G(g);
    ll ans = 0;
    for(int i = 0; i < n; i++)ans += G.dist(i, i + 1 == n ? 0 : i + 1);
    cout << ans << '\n';
}
accuracy: 0.175
time_ms: 2740
memory_kb: 234208
final_rank: 18

code_snippet: #include <iostream>
#include <vector>
#include <string>
#include <queue>
#include <array>
#include <algorithm>
#include <numeric>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <set>
#include <cassert>
#include <iterator>
#include <random>
#include <stack>
#include <climits>

long long int solve(const int n, const int m, const std::vector<std::tuple<int, int, int>> edges) {
	std::vector<std::tuple<int, int, int>> unused;
	std::vector<std::vector<std::pair<int, int>>> tree(n);
	std::vector<bool> visit(n, false);
	std::vector<int> depth(n, 0);
	{
		std::vector<std::vector<std::pair<int, int>>> graph(n);
		for (const auto [a, b, c] : edges) {
			graph[a].emplace_back(b, c);
		}
		std::queue<int> queue;
		visit[0] = true;
		queue.push(0);
		while (!queue.empty()) {
			const auto top = queue.front(); queue.pop();
			for (const auto [to, c] : graph[top]) {
				if (visit[to]) {
					unused.emplace_back(top, to, c);
				}
				else {
					tree[top].emplace_back(to, c);
					visit[to] = true;
					depth[to] = depth[top] + c;
					queue.push(to);
				}
			}
		}
	}
	std::vector<int> all_unused;
	for (const auto [a, b, _] : unused) {
		all_unused.push_back(a);
		all_unused.push_back(b);
	}
	std::sort(all_unused.begin(), all_unused.end()); all_unused.erase(std::unique(all_unused.begin(), all_unused.end()), all_unused.end());
	std::vector<int> in_order(n), out_order(n), nearest_unuse(n, -1);
	{
		for (auto i = 0; i < all_unused.size(); ++i) {
			nearest_unuse[all_unused[i]] = i;
		}
		int order{ 0 };
		std::stack<int> stack;
		std::fill(visit.begin(), visit.end(), false);
		stack.push(0);
		while (!stack.empty()) {
			const auto top = stack.top(); stack.pop();
			if (top >= 0) {
				if (visit[top]) continue;
				visit[top] = true;
				in_order[top] = order++;
				stack.push(-1 - top);
				for (const auto [to, c] : tree[top]) {
					if (visit[to]) continue;
					stack.push(to);
					if (nearest_unuse[to] >= 0 && all_unused[nearest_unuse[to]] == to) continue;
					nearest_unuse[to] = nearest_unuse[top];
				}
			}
			else {
				out_order[-1 - top] = order;
			}
		}
	}
	const auto is_parent = [&in_order, &out_order](const int a, const int b) {
		return in_order[a] <= in_order[b] && out_order[b] <= out_order[a];
	};
	std::vector<std::vector<long long int>> unused_distance(all_unused.size(), std::vector<long long int>(all_unused.size(), LLONG_MAX));
	{
		std::vector<std::vector<std::pair<int, int>>> graph(all_unused.size());
		for (const auto [a, b, c] : unused) {
			const auto i = std::distance(all_unused.begin(), std::lower_bound(all_unused.begin(), all_unused.end(), a));
			const auto j = std::distance(all_unused.begin(), std::lower_bound(all_unused.begin(), all_unused.end(), b));
			graph[i].emplace_back(j, c);
		}
		for (auto i = 0; i < all_unused.size(); ++i) {
			int parent{ -1 };
			for (auto j = 0; j < all_unused.size(); ++j) {
				if (i == j) continue;
				if (!is_parent(all_unused[j], all_unused[i])) continue;
				if (parent == -1 || depth[all_unused[parent]] < depth[all_unused[j]]) {
					parent = j;
				}
			}
			if (parent >= 0)
				graph[parent].emplace_back(i, depth[all_unused[i]] - depth[all_unused[parent]]);
		}
		const auto comparator = [](const auto a, const auto b) {return a.second > b.second; };
		std::priority_queue<std::pair<int, long long int>, std::vector<std::pair<int, long long int>>, decltype(comparator)> queue(comparator);
		for (auto i = 0; i < all_unused.size(); ++i) {
			auto& min_distance = unused_distance[i];
			min_distance[i] = 0;
			queue.emplace(i, 0);
			while (!queue.empty()) {
				const auto [top, cost] = queue.top(); queue.pop();
				if (min_distance[top] < cost) continue;
				for (const auto [to, c] : graph[top]) {
					if (min_distance[to] > cost + c) {
						min_distance[to] = cost + c;
						queue.emplace(to, cost + c);
					}
				}
			}
		}
	}
	long long int result{ 0 };
	for (auto i = 0; i < n; ++i) {
		const auto j = (i + 1) % n;
		long long int current{ LLONG_MAX };
		if (is_parent(i, j)) {
			current = std::min<long long int>(current, depth[j] - depth[i]);
		}
		if (nearest_unuse[j] >= 0) {
			const auto k = nearest_unuse[j];
			const long long int k_to_j = depth[j] - depth[all_unused[k]];
			for (auto l = 0; l < all_unused.size(); ++l) {
				const auto m = all_unused[l];
				if (!is_parent(i, m) || unused_distance[l][k] == LLONG_MAX) continue;
				const auto i_to_l = depth[m] - depth[i];
				const auto cost = i_to_l + unused_distance[l][k] + k_to_j;
				current = std::min(current, cost);
			}
		}
		if (current == LLONG_MAX) {
			return -1;
		}
		result += current;
	}
	return result;
}

long long int brute(const int n, const int m, const std::vector<std::tuple<int, int, int>> edges) {
	std::vector<std::vector<std::pair<int, int>>> graph(n);
	for (const auto [a, b, c] : edges) {
		graph[a].emplace_back(b, c);
	}
	const auto comparator = [](const auto a, const auto b) {return a.second > b.second; };
	std::priority_queue<std::pair<int, long long int>, std::vector<std::pair<int, long long int>>, decltype(comparator)> queue(comparator);
	long long int result{ 0 };
	for (auto i = 0; i < n; ++i) {
		const auto j = (i + 1) % n;
		std::vector<long long int> min_distance(n, LLONG_MAX);
		min_distance[i] = 0;
		queue.emplace(i, 0);
		while (!queue.empty()) {
			const auto [top, cost] = queue.top(); queue.pop();
			if (min_distance[top] < cost) continue;
			for (const auto [to, c] : graph[top]) {
				if (min_distance[to] > cost + c) {
					min_distance[to] = cost + c;
					queue.emplace(to, cost + c);
				}
			}
		}
		if (min_distance[j] == LLONG_MAX) {
			return -1;
		}
		result += min_distance[j];
	}
	return result;
}
int main() {
	int n, m; std::cin >> n >> m;
	std::vector<std::tuple<int, int, int>> edges(m);
	for (auto& [a, b, c] : edges) {
		std::cin >> a >> b >> c; --a; --b;
	}
	std::cout << solve(n, m, edges) << '\n';
}
accuracy: 1
time_ms: 450
memory_kb: 20416
final_rank: 3

code_snippet: #include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; (i) < int(n); ++ (i))
#define ALL(x) begin(x), end(x)
using ll = long long;
using namespace std;
template <class T> inline void chmin(T & a, T const & b) { a = min(a, b); }

vector<int> dijkstra(vector<vector<pair<int, int> > > const & g, int root) {
    vector<int> dist(g.size(), INT_MAX);
    priority_queue<pair<int, int> > que;
    dist[root] = 0;
    que.emplace(- dist[root], root);
    while (not que.empty()) {
        int dist_i; int i; tie(dist_i, i) = que.top(); que.pop();
        if (dist[i] < - dist_i) continue;
        for (auto it : g[i]) {
            int j; int cost; tie(j, cost) = it;
            if (- dist_i + cost < dist[j]) {
                dist[j] = - dist_i + cost;
                que.emplace(dist_i - cost, j);
            }
        }
    }
    return dist;
}

vector<vector<int> > warshall_floyd(vector<vector<pair<int, int> > > const & g) {
    int n = g.size();
    vector<vector<int> > dist(n, vector<int>(n, INT_MAX));
    REP (i, n) {
        dist[i][i] = 0;
        for (auto edge : g[i]) {
            int j, cost; tie(j, cost) = edge;
            dist[i][j] = cost;
        }
    }
    REP (k, n) {
        REP (i, n) if (dist[i][k] != INT_MAX) {
            REP (j, n) if (dist[k][j] != INT_MAX) {
                chmin(dist[i][j], dist[i][k] + dist[k][j]);
            }
        }
    }
    return dist;
}

template <class Monoid>
struct sparse_table {
    typedef typename Monoid::underlying_type underlying_type;
    vector<vector<underlying_type> > table;
    Monoid mon;
    sparse_table() = default;
    sparse_table(vector<underlying_type> const & data, Monoid const & a_mon = Monoid())
            : mon(a_mon) {
        int n = data.size();
        int log_n = 32 - __builtin_clz(n);
        table.resize(log_n, vector<underlying_type>(n, mon.unit()));
        table[0] = data;
        for (int k = 0; k < log_n-1; ++ k) {
            for (int i = 0; i < n; ++ i) {
                table[k+1][i] = mon.append(table[k][i], i + (1ll<<k) < n ? table[k][i + (1ll<<k)] : mon.unit());
            }
        }
    }
    underlying_type range_concat(int l, int r) const {
        assert (0 <= l and l <= r and r <= table[0].size());
        if (l == r) return mon.unit();
        int k = 31 - __builtin_clz(r - l);  // log2
        return mon.append(table[k][l], table[k][r - (1ll<<k)]);
    }
};
struct indexed_min_monoid {
    typedef pair<int, int> underlying_type;
    underlying_type unit() const { return { INT_MAX, INT_MAX }; }
    underlying_type append(underlying_type a, underlying_type b) const { return min(a, b); }
};
struct lowest_common_ancestor {
    sparse_table<indexed_min_monoid> table;
    vector<int> index;
    lowest_common_ancestor() = default;
    lowest_common_ancestor(int root, vector<vector<int> > const & g) {
        vector<pair<int, int> > tour;
        index.assign(g.size(), -1);
        function<void (int, int, int)> go = [&](int i, int parent, int depth) {
            index[i] = tour.size();
            tour.emplace_back(depth, i);
            for (int j : g[i]) if (j != parent) {
                go(j, i, depth + 1);
                tour.emplace_back(depth, i);
            }
        };
        go(root, -1, 0);
        table = sparse_table<indexed_min_monoid>(tour);
    }
    int operator () (int x, int y) const {
        x = index[x];
        y = index[y];
        if (x > y) swap(x, y);
        return table.range_concat(x, y + 1).second;
    }
};

ll solve(int n, int m, vector<vector<pair<int, int> > > & g) {

    // erase duplicated edges
    REP (i, n) {
        sort(ALL(g[i]));
        g[i].erase(unique(ALL(g[i]), [&](pair<int, int> e1, pair<int, int> e2) {
            return e1.first == e2.first;
        }), g[i].end());
    }

    // calculate shortest-paths and check the possibility
    constexpr int root = 0;
    vector<int> dist_root = dijkstra(g, root);
    if (count(ALL(dist_root), INT_MAX)) {
        return -1;
    }
    vector<vector<pair<int, int> > > rev_g(n);
    REP (i, n) {
        for (auto edge : g[i]) {
            int j, cost; tie(j, cost) = edge;
            rev_g[j].emplace_back(i, cost);
        }
    }
    auto rev_dist_root = dijkstra(rev_g, root);
    if (count(ALL(rev_dist_root), INT_MAX)) {
        return -1;
    }

    // make a shortest-path tree; collect the unused edges
    vector<vector<int> > children(n);
    vector<int> parent(n, -1);
    vector<vector<pair<int, int> > > unused_edges(n);
    REP (i, n) {
        for (auto edge : g[i]) {
            int j, cost; tie(j, cost) = edge;
            if (dist_root[i] + cost == dist_root[j] and parent[j] == -1) {
                children[i].push_back(j);
                parent[j] = i;
            } else {
                unused_edges[i].emplace_back(j, cost);
            }
        }
    }

    // select and reorder distinguished vertices
    map<int, int> distinguished;
    auto distinguished_insert = [&](int i) {
        if (not distinguished.count(i)) {
            distinguished.emplace(i, distinguished.size());
        }
    };
    distinguished_insert(0);
    REP (i, n) {
        if (not unused_edges[i].empty()) {
            distinguished_insert(i);
        }
        for (auto edge : unused_edges[i]) {
            int j = edge.first;
            distinguished_insert(j);
        }
    }

    // compute distances for all distinguished vertices; find the lowest distinguished ancestors for each vertex
    vector<vector<pair<int, int> > > h(distinguished.size());
    REP (i, n) {
        for (auto edge : unused_edges[i]) {
            int j, cost; tie(j, cost) = edge;
            h[distinguished[i]].emplace_back(distinguished[j], cost);
        }
    }
    vector<int> ancestor(n, -1);
    function<void (int, int)> go = [&](int i, int last) {
        if (distinguished.count(i)) {
            if (last != -1) {
                h[distinguished[last]].emplace_back(distinguished[i], dist_root[i] - dist_root[last]);
            }
            last = i;
        }
        ancestor[i] = last;
        for (int j : children[i]) {
            go(j, last);
        }
    };
    go(root, -1);
    auto dist = warshall_floyd(h);

    // prepare the lca for the shortest-path tree
    lowest_common_ancestor lca(root, children);

    // compute the result
    ll result = 0;
    REP (i, n) {
        int j = (i + 1) % n;
        if (lca(i, j) == i) {
            result += dist_root[j] - dist_root[i];
        } else {
            int acc = INT_MAX;
            for (auto it : distinguished) {
                int k, distinguished_k; tie(k, distinguished_k) = it;
                if (lca(i, k) == i) {
                    chmin(acc, (dist_root[k] - dist_root[i]) + dist[distinguished_k][distinguished[ancestor[j]]] + (dist_root[j] - dist_root[ancestor[j]]));
                }
            }
            result += acc;
        }
    }

    return result;
}

int main() {
    // input
    int n, m; scanf("%d%d", &n, &m);
    vector<vector<pair<int, int> > > g(n);
    REP (i, m) {
        int a, b, c; scanf("%d%d%d", &a, &b, &c);
        -- a; -- b;
        g[a].emplace_back(b, c);
    }
    // solve
    ll result = solve(n, m, g);
    // output
    printf("%lld\n", result);
    return 0;
}
accuracy: 1
time_ms: 2680
memory_kb: 62764
final_rank: 7

code_snippet: #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>
 
using namespace std;

/* constant */

const int MAX_N = 100000;
const int MAX_M = MAX_N + 500;
const int MAX_GN = 1000;

const int INF = 1 << 30;

/* typedef */

typedef vector<int> vi;
typedef pair<int,int> pii;
typedef vector<pii> vpii;

struct Edge {
  int gi, gj, gc;
  Edge() {}
  Edge(int _gi, int _gj, int _gc): gi(_gi), gj(_gj), gc(_gc) {}
};

typedef vector<Edge *> ve;

/* global variables */

vpii nbrs[MAX_N];
int ins[MAX_N], outs[MAX_N];
int gids[MAX_N], g2i[MAX_GN], eids[MAX_N], dists[MAX_GN];
Edge edges[MAX_GN];
vi gnbrs[MAX_GN];

/* subroutines */

/* main */

int main() {
  int n, m;
  cin >> n >> m;

  memset(ins, 0, sizeof(ins));
  memset(outs, 0, sizeof(outs));

  for (int i = 0; i < m; i++) {
    int a, b, c;
    cin >> a >> b >> c;
    a--, b--;

    nbrs[a].push_back(pii(b, c));
    outs[a]++;
    ins[b]++;
  }

  int gn = 0;
  memset(gids, -1, sizeof(gids));
  
  for (int i = 0; i < n; i++) {
    if (ins[i] == 0 || outs[i] == 0) {
      cout << -1 << endl;
      return 0;
    }
    if (ins[i] > 1 || outs[i] > 1)
      gids[i] = gn, g2i[gn++] = i;
  }
  //printf("gn=%d\n", gn);

  if (gn == 0) {
    int csum = 0;
    for (int i = 0; i < n; i++) {
      int j = (i + 1) % n;
      for (int ui = i; ui != j;) {
	pii& v = nbrs[ui].front();
	ui = v.first;
	csum += v.second;
      }
    }
    cout << csum << endl;
    return 0;
  }
  
  int en = 0;
  memset(eids, -1, sizeof(eids));

  for (int gi = 0; gi < gn; gi++) {
    int st = g2i[gi];
    vpii& nbr = nbrs[st];

    for (vpii::iterator vit = nbr.begin(); vit != nbr.end(); vit++) {
      int ui = vit->first;
      int csum = vit->second;

      Edge& eu = edges[en];

      while (gids[ui] < 0) {
	eids[ui] = en;
	pii& u = nbrs[ui].front();
	ui = u.first;
	csum += u.second;
      }

      eu.gi = gi;
      eu.gj = gids[ui];
      eu.gc = csum;

      gnbrs[gi].push_back(en++);
      //printf("edge[%d]: %d,%d,%d\n", en-1, eu.gi, eu.gj, eu.gc);
    }
  }
  //printf("en=%d\n", en);

  int csum = 0;

  for (int i0 = 0; i0 < n; i0++) {
    int st = i0;
    int gl = (i0 + 1) % n;

    int gi0 = gids[st];
    //printf("gi0=%d,gi1=%d,ei0=%d,ei1=%d\n", gi0, gi1, ei0, ei1);

    if (gi0 < 0) {
      while (st != gl && gids[st] < 0) {
	pii& u = nbrs[st].front();
	csum += u.second;
	st = u.first;
      }
      gi0 = gids[st];
      if (st == gl) continue;
    }

    int gi1 = (gids[gl] >= 0) ? gids[gl] : edges[eids[gl]].gi;
    
    for (int i = 0; i < gn; i++) dists[i] = INF;
    dists[gi0] = 0;

    priority_queue<pii,vpii,greater<pii> > q;
    q.push(pii(0, gi0));

    while (! q.empty()) {
      pii u = q.top(); q.pop();
      int& ud = u.first;
      int& ui = u.second;

      if (ud != dists[ui]) continue;
      if (ui == gi1) break;

      vi& gnbr = gnbrs[ui];
      for (vi::iterator vit = gnbr.begin(); vit != gnbr.end(); vit++) {
	int& vi = edges[*vit].gj;
	int nvd = ud + edges[*vit].gc;
	if (dists[vi] > nvd) {
	  dists[vi] = nvd;
	  q.push(pii(nvd, vi));
	}
      }
    }

    if (dists[gi1] >= INF) {
      cout << -1 << endl;
      return 0;
    }

    csum += dists[gi1];

    st = g2i[gi1];
    while (st != gl) {
      pii& u = nbrs[st].front();
      st = u.first;
      csum += u.second;
    }
  }

  cout << csum << endl;

  return 0;
}
accuracy: 0.15
time_ms: 50
memory_kb: 7248
final_rank: 19

code_snippet: #define _USE_MATH_DEFINES
#include <algorithm>
#include <cstdio>
#include <functional>
#include <iostream>
#include <cfloat>
#include <climits>
#include <cstring>
#include <cmath>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <time.h>
#include <vector>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> i_i;
typedef pair<ll, int> ll_i;
typedef pair<double, int> d_i;
typedef pair<ll, ll> ll_ll;
typedef pair<double, double> d_d;
struct edge { int v, w; };

ll MOD = 1000000007;
ll _MOD = 1000000009;
double EPS = 1e-10;
int INF = INT_MAX / 4;

void dijkstra(int n, vector<vector<edge> >& G, int s, vector<int>& d) {
	d[s] = 0;
	priority_queue<i_i, vector<i_i>, greater<i_i> > q;
	q.push(i_i(0, s));
	while (!q.empty()) {
		i_i p = q.top(); q.pop();
		int u = p.second;
		if (p.first > d[u]) continue;
		for (int i = 0; i < G[u].size(); i++) {
			edge e = G[u][i];
			if (d[e.v] > d[u] + e.w) {
				d[e.v] = d[u] + e.w;
				q.push(i_i(d[e.v], e.v));
			}
		}
	}
}

int unko = 0;

void dfs(int u, vector<vector<edge> >& g, vector<int>& in, vector<bool>& vis, vector<vector<edge> >& G, vector<i_i>& a, vector<i_i>& b, vector<int>& c) {
	if (vis[u]) return;
	vis[u] = true;
	a[u] = b[u] = i_i(u, 0);
	for (int i = 0; i < g[u].size(); i++) {
		edge e = g[u][i];
		edge f;
		int sum = 0;
		for (f = e; in[f.v] == 1 && g[f.v].size() == 1; f = g[f.v][0])
			sum += f.w;
		sum += f.w;
		edge E = {f.v, sum};
		G[u].push_back(E);
		int x = 0;
		for (f = e; in[f.v] == 1 && g[f.v].size() == 1; f = g[f.v][0]) {
			x += f.w;
			a[f.v] = i_i(E.v, sum - x);
			b[f.v] = i_i(u, x);
			c[f.v] = unko;
		}
		unko++;
		dfs(E.v, g, in, vis, G, a, b, c);
	}
}

int main() {
	int N, M;
	cin >> N >> M;
	vector<int> in(N);
	vector<vector<edge> > g(N);
	in[0]++;
	edge e = {0, 0};
	g[0].push_back(e);
	while (M--) {
		int a, b, c;
		cin >> a >> b >> c;
		a--; b--;
		in[b]++;
		edge e = {b, c};
		g[a].push_back(e);
	}
	for (int u = 0; u < N; u++)
		if (in[u] == 0 || g[u].empty()) {
			cout << -1 << endl;
			return 0;
		}
	vector<bool> vis(N);
	vector<vector<edge> > G(N);
	vector<i_i> a(N), b(N);
	vector<int> c(N, -1);
	dfs(0, g, in, vis, G, a, b, c);
	for (int u = 0; u < N; u++)
		if (c[u] == -1 && !vis[u]) {
			cout << -1 << endl;
			return 0;
		}
	vector<int> hoge;
	for (int u = 0; u < N; u++)
		if (c[u] == -1)
			hoge.push_back(u);
	int n = hoge.size();
	vector<vector<int> > d(n, vector<int>(n, INF));
	for (int i = 0; i < n; i++) d[i][i] = 0;
	for (int i = 0; i < n; i++) {
		int u = hoge[i];
		for (int k = 0; k < G[u].size(); k++) {
			edge e = G[u][k];
			int j = lower_bound(hoge.begin(), hoge.end(), e.v) - hoge.begin();
			d[i][j] = min(d[i][j], e.w);
		}
	}
	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 = 0;
	for (int u = 0; u < N; u++) {
		int v = (u + 1) % N;
		if (c[u] != -1 && c[v] != -1 && c[u] == c[v] && b[u].second < b[v].second) {
			ans += b[v].second - b[u].second;
			continue;
		}
		int s = a[u].first, t = b[v].first;
		ans += a[u].second + b[v].second;
		int i = lower_bound(hoge.begin(), hoge.end(), s) - hoge.begin();
		int j = lower_bound(hoge.begin(), hoge.end(), t) - hoge.begin();
		if (d[i][j] == INF) {
			cout << -1 << endl;
			return 0;
		}
		ans += d[i][j];
	}
	cout << ans << endl;
}
accuracy: 1
time_ms: 1230
memory_kb: 15456
final_rank: 6

code_snippet: #define _USE_MATH_DEFINES
#include <algorithm>
#include <cstdio>
#include <functional>
#include <iostream>
#include <cfloat>
#include <climits>
#include <cstring>
#include <cmath>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <time.h>
#include <vector>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> i_i;
typedef pair<ll, int> ll_i;
typedef pair<double, int> d_i;
typedef pair<ll, ll> ll_ll;
typedef pair<double, double> d_d;
struct edge { int v, w; };

ll MOD = 1000000007;
ll _MOD = 1000000009;
double EPS = 1e-10;
int INF = INT_MAX / 4;

void dijkstra(int n, vector<vector<edge> >& G, int s, vector<int>& d) {
	d[s] = 0;
	priority_queue<i_i, vector<i_i>, greater<i_i> > q;
	q.push(i_i(0, s));
	while (!q.empty()) {
		i_i p = q.top(); q.pop();
		int u = p.second;
		if (p.first > d[u]) continue;
		for (int i = 0; i < G[u].size(); i++) {
			edge e = G[u][i];
			if (d[e.v] > d[u] + e.w) {
				d[e.v] = d[u] + e.w;
				q.push(i_i(d[e.v], e.v));
			}
		}
	}
}

int unko = 0;

void dfs(int u, vector<vector<edge> >& g, vector<int>& in, vector<bool>& vis, vector<vector<edge> >& G, vector<i_i>& a, vector<i_i>& b, vector<int>& c) {
	if (vis[u]) return;
	vis[u] = true;
	a[u] = b[u] = i_i(u, 0);
	for (int i = 0; i < g[u].size(); i++) {
		edge e = g[u][i];
		edge f;
		int sum = 0;
		for (f = e; in[f.v] == 1 && g[f.v].size() == 1; f = g[f.v][0])
			sum += f.w;
		sum += f.w;
		edge E = {f.v, sum};
		G[u].push_back(E);
		int x = 0;
		for (f = e; in[f.v] == 1 && g[f.v].size() == 1; f = g[f.v][0]) {
			x += f.w;
			a[f.v] = i_i(E.v, sum - x);
			b[f.v] = i_i(u, x);
			c[f.v] = unko;
		}
		unko++;
		dfs(E.v, g, in, vis, G, a, b, c);
	}
}

int main() {
	int N, M;
	cin >> N >> M;
	vector<int> in(N);
	vector<vector<edge> > g(N);
	in[0]++;
	edge e = {0, 0};
	g[0].push_back(e);
	while (M--) {
		int a, b, c;
		cin >> a >> b >> c;
		a--; b--;
		in[b]++;
		edge e = {b, c};
		g[a].push_back(e);
	}
	for (int u = 0; u < N; u++)
		if (in[u] == 0 || g[u].empty()) {
			cout << -1 << endl;
			return 0;
		}
	vector<bool> vis(N);
	vector<vector<edge> > G(N);
	vector<i_i> a(N), b(N);
	vector<int> c(N, -1);
	dfs(0, g, in, vis, G, a, b, c);
	for (int u = 0; u < N; u++)
		if (c[u] == -1 && !vis[u]) {
			cout << -1 << endl;
			return 0;
		}
	vector<int> hoge;
	for (int u = 0; u < N; u++)
		if (c[u] == -1)
			hoge.push_back(u);
	int n = hoge.size();
	vector<vector<int> > d(n, vector<int>(n, INF));
	for (int i = 0; i < n; i++) d[i][i] = 0;
	for (int i = 0; i < n; i++) {
		int u = hoge[i];
		for (int k = 0; k < G[u].size(); k++) {
			edge e = G[u][k];
			int j = lower_bound(hoge.begin(), hoge.end(), e.v) - hoge.begin();
			d[i][j] = min(d[i][j], e.w);
		}
	}
	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 = 0;
	for (int u = 0; u < N; u++) {
		int v = (u + 1) % N;
		if (c[u] != -1 && c[v] != -1 && c[u] == c[v] && b[u].second < b[v].second) {
			ans += b[v].second - b[u].second;
			continue;
		}
		int s = a[u].first, t = b[v].first;
		ans += a[u].second + b[v].second;
		int i = lower_bound(hoge.begin(), hoge.end(), s) - hoge.begin();
		int j = lower_bound(hoge.begin(), hoge.end(), t) - hoge.begin();
		ans += d[i][j];
	}
	cout << ans << endl;
}
accuracy: 0.175
time_ms: 600
memory_kb: 10772
final_rank: 16

code_snippet: #define _USE_MATH_DEFINES
#include <algorithm>
#include <cstdio>
#include <functional>
#include <iostream>
#include <cfloat>
#include <climits>
#include <cstring>
#include <cmath>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <time.h>
#include <vector>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> i_i;
typedef pair<ll, int> ll_i;
typedef pair<double, int> d_i;
typedef pair<ll, ll> ll_ll;
typedef pair<double, double> d_d;
struct edge { int v, w; };

ll MOD = 1000000007;
ll _MOD = 1000000009;
double EPS = 1e-10;
int INF = INT_MAX / 2;

void dijkstra(int n, vector<vector<edge> >& G, int s, vector<int>& d) {
	d[s] = 0;
	priority_queue<i_i, vector<i_i>, greater<i_i> > q;
	q.push(i_i(0, s));
	while (!q.empty()) {
		i_i p = q.top(); q.pop();
		int u = p.second;
		if (p.first > d[u]) continue;
		for (int i = 0; i < G[u].size(); i++) {
			edge e = G[u][i];
			if (d[e.v] > d[u] + e.w) {
				d[e.v] = d[u] + e.w;
				q.push(i_i(d[e.v], e.v));
			}
		}
	}
}

int unko = 0;

void dfs(int u, vector<vector<edge> >& g, vector<int>& in, vector<bool>& vis, vector<vector<edge> >& G, vector<i_i>& a, vector<i_i>& b, vector<int>& c) {
	if (vis[u]) return;
	vis[u] = true;
	a[u] = b[u] = i_i(u, 0);
	for (int i = 0; i < g[u].size(); i++) {
		edge e = g[u][i];
		edge f;
		int sum = 0;
		for (f = e; in[f.v] == 1 && g[f.v].size() == 1; f = g[f.v][0])
			sum += f.w;
		sum += f.w;
		edge E = {f.v, sum};
		G[u].push_back(E);
		int x = 0;
		for (f = e; in[f.v] == 1 && g[f.v].size() == 1; f = g[f.v][0]) {
			x += f.w;
			a[f.v] = i_i(E.v, sum - x);
			b[f.v] = i_i(u, x);
			c[f.v] = unko;
		}
		unko++;
		dfs(E.v, g, in, vis, G, a, b, c);
	}
}

int main() {
	int N, M;
	cin >> N >> M;
	vector<int> in(N);
	vector<vector<edge> > g(N);
	in[0]++;
	edge e = {0, 0};
	g[0].push_back(e);
	while (M--) {
		int a, b, c;
		cin >> a >> b >> c;
		a--; b--;
		in[b]++;
		edge e = {b, c};
		g[a].push_back(e);
	}
	for (int u = 0; u < N; u++)
		if (in[u] == 0 || g[u].empty()) {
			cout << -1 << endl;
			return 0;
		}
	vector<bool> vis(N);
	vector<vector<edge> > G(N);
	vector<i_i> a(N), b(N);
	vector<int> c(N, -1);
	dfs(0, g, in, vis, G, a, b, c);
	for (int u = 0; u < N; u++)
		if (c[u] == -1 && !vis[u]) {
			cout << -1 << endl;
			return 0;
		}
	vector<int> hoge;
	for (int u = 0; u < N; u++)
		if (c[u] == -1)
			hoge.push_back(u);
	ll ans = 0;
	vector<int> d(N);
	for (int u = 0; u < N; u++) {
		int v = (u + 1) % N;
		if (c[u] != -1 && c[v] != -1 && c[u] == c[v] && b[u].second < b[v].second) {
			ans += b[v].second - b[u].second;
			continue;
		}
		int s = a[u].first, t = b[v].first;
		ans += a[u].second + b[v].second;
		for (int i = 0; i < hoge.size(); i++)
			d[hoge[i]] = INT_MAX;
		dijkstra(N, G, s, d);
		ans += d[t];
	}
	cout << ans << endl;
}
accuracy: 0.175
time_ms: 3630
memory_kb: 8660
final_rank: 17