Problem p03306 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9;
const int MOD = 1e9 + 7;
// const int MOD=998244353;
const long long LINF = 1e18;
#define int long long
// template
/*
考察
一点値決めればあとは自動で決まる気がする
0にiを入れたときの各値をiで表してあげて、可能の範囲を見て決定
0にiを入れてトポロジカルチックにやる？
とりあえずBFSとかで適当にやって、最後にその範囲とかからガンバルンバ
*/
template <typename T> void fin(T a) {
  cout << a << endl;
  exit(0);
}
// main
signed main() {
  int N, M;
  cin >> N >> M;
  typedef pair<int, int> P;
  std::vector<P> edge[N];
  while (M--) {
    int u, v, s;
    cin >> u >> v >> s;
    u--;
    v--;
    edge[u].push_back(P(v, s));
    edge[v].push_back(P(u, s));
  }
  std::vector<P> val[N];
  val[0].push_back(P(0, 1));
  queue<P> que; // 親、子
  std::vector<int> used(N, 0);
  que.push(P(-1, 0));
  while (que.size()) {
    P p = que.front();
    que.pop();
    int pa = p.first, now = p.second;
    if (used[now])
      continue;
    used[now]++;
    for (auto q : edge[now]) {
      int po = q.first, we = q.second;
      if (po == pa)
        continue;
      val[po].push_back(P(we - val[now][0].first, -val[now][0].second));
      if (!used[po])
        que.push(P(now, po));
    }
  }
  int ans_i = -LINF, tmp;
  for (int i = 0; i < N; i++) {
    for (int j = 1; j < val[i].size(); j++) {
      if (val[i][0] == val[i][j])
        continue;
      int n = val[i][0].second - val[i][j].second;
      int num = val[i][j].first - val[i][0].first;
      if (abs(num) % abs(n))
        fin(0);
      tmp = num / n;
      // cout<<i<<" "<<j<<" "<<val[i][0].first<<" "<<val[i][0].second<<"
      // "<<val[i][j].first<<" "<<val[i][j].second<<" "<<ans_i<<" "<<tmp<<endl;
      if (ans_i > -LINF && ans_i != tmp)
        fin(0);
      ans_i = tmp;
    }
  }
  if (ans_i > -LINF) {
    for (int i = 0; i < N; i++)
      if (val[i][0].first + val[i][0].second * ans_i <= 0)
        fin(0);
    fin(1);
  }
  int mn = -LINF, mx = LINF;
  for (int i = 0; i < N; i++) {
    int num = val[i][0].first, n = val[i][0].second;
    if (!n) {
      if (val[i][0].first > 0)
        continue;
      fin(0);
    }
    if (n > 0) { // num<n*aになるようにaを設定（mnを）
      mn = max(mn, (-num) / n + 1);
    } else { // num<n*aになるようにaを設定(mxを)
      tmp = num / (-n);
      if (!(abs(num) % abs(n)))
        tmp--;
      mx = min(mx, tmp);
    }
  }
  // for(int i=0;i<N;i++)cout<<"VAL"<<val[i][0].first<<"
  // "<<val[i][0].second<<endl; cout<<mn<<" "<<mx<<endl;
  fin(max(0LL, mx - mn + 1));
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9;
const int MOD = 1e9 + 7;
// const int MOD=998244353;
const long long LINF = 1e18;
#define int long long
// template
/*
考察
一点値決めればあとは自動で決まる気がする
0にiを入れたときの各値をiで表してあげて、可能の範囲を見て決定
0にiを入れてトポロジカルチックにやる？
とりあえずBFSとかで適当にやって、最後にその範囲とかからガンバルンバ
*/
template <typename T> void fin(T a) {
  cout << a << endl;
  exit(0);
}
// main
signed main() {
  int N, M;
  cin >> N >> M;
  typedef pair<int, int> P;
  std::vector<P> edge[N];
  while (M--) {
    int u, v, s;
    cin >> u >> v >> s;
    u--;
    v--;
    edge[u].push_back(P(v, s));
    edge[v].push_back(P(u, s));
  }
  std::vector<P> val[N];
  val[0].push_back(P(0, 1));
  queue<P> que; // 親、子
  std::vector<int> used(N, 0);
  que.push(P(-1, 0));
  while (que.size()) {
    P p = que.front();
    que.pop();
    int pa = p.first, now = p.second;
    if (used[now])
      continue;
    used[now]++;
    for (auto q : edge[now]) {
      int po = q.first, we = q.second;
      if (po == pa)
        continue;
      val[po].push_back(P(we - val[now][0].first, -val[now][0].second));
      if (!used[po])
        que.push(P(now, po));
    }
  }
  int ans_i = -LINF, tmp;
  for (int i = 0; i < N; i++) {
    for (int j = 1; j < val[i].size(); j++) {
      if (val[i][0] == val[i][j])
        continue;
      int n = val[i][0].second - val[i][j].second;
      int num = val[i][j].first - val[i][0].first;
      if (!n)
        fin(0);
      if (abs(num) % abs(n))
        fin(0);
      tmp = num / n;
      // cout<<i<<" "<<j<<" "<<val[i][0].first<<" "<<val[i][0].second<<"
      // "<<val[i][j].first<<" "<<val[i][j].second<<" "<<ans_i<<" "<<tmp<<endl;
      if (ans_i > -LINF && ans_i != tmp)
        fin(0);
      ans_i = tmp;
    }
  }
  if (ans_i > -LINF) {
    for (int i = 0; i < N; i++)
      if (val[i][0].first + val[i][0].second * ans_i <= 0)
        fin(0);
    fin(1);
  }
  int mn = -LINF, mx = LINF;
  for (int i = 0; i < N; i++) {
    int num = val[i][0].first, n = val[i][0].second;
    if (!n) {
      if (val[i][0].first > 0)
        continue;
      fin(0);
    }
    if (n > 0) { // num<n*aになるようにaを設定（mnを）
      mn = max(mn, (-num) / n + 1);
    } else { // num<n*aになるようにaを設定(mxを)
      tmp = num / (-n);
      if (!(abs(num) % abs(n)))
        tmp--;
      mx = min(mx, tmp);
    }
  }
  // for(int i=0;i<N;i++)cout<<"VAL"<<val[i][0].first<<"
  // "<<val[i][0].second<<endl; cout<<mn<<" "<<mx<<endl;
  fin(max(0LL, mx - mn + 1));
}