Problem p01324 (C++) — buggy submission, verdict: Runtime Error

#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <map>
#include <set>
#include <sstream>
#include <vector>
#define F first
#define S second
#define inf (1 << 28)
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
using namespace std;

struct P {
  string unit;
  int mpower;
  int upower;
  P(string unit = "$", int upower = -inf, int mpower = -inf)
      : unit(unit), upower(upower), mpower(mpower) {}
};
vector<vector<P>> G(210);
map<string, int> exist;

int toPower(string s) {
  if (s == "1")
    return 0;
  int pos = 0;
  rep(i, s.size()) {
    if (s[i] == '^') {
      pos = i + 1;
      break;
    }
  }
  return (atoi)(s.substr(pos, s.size() - pos).c_str());
}

bool used[210];
int isok; //-1 -> No, 0 => Not yet, 1 -> Ok

void dfs(string now, string target, int power, int target_power) {
  if (isok != 0)
    return;
  if (now == target) {
    isok = (power == target_power ? 1 : -1);
    return;
  }
  int index = exist[now];
  if (used[index])
    return;
  used[index] = true;

  rep(i, G[index].size()) {
    P p = G[index][i];
    int next_index = exist[p.unit];
    if (used[next_index])
      continue;
    dfs(p.unit, target, power + (p.mpower == 0 ? p.upower : -p.mpower),
        target_power);
  }
}

bool check(string u1, string u2, int power) {
  rep(i, 110) used[i] = false;
  isok = 0;

  dfs(u1, u2, 0, power);
  return isok == 1;
}

bool reachable;

void move(int now, int target) {
  if (now == target) {
    reachable = true;
    return;
  }

  if (used[now])
    return;
  used[now] = true;

  rep(i, G[now].size()) {

    assert(exist.count(G[now][i].unit));

    move(exist[G[now][i].unit], target);
  }
}

int main() {
  int N;
  while (cin >> N, N) {
    assert(N <= 100);
    rep(i, N) G[i].clear();
    int index = 0;
    exist.clear();
    bool result = true;
    rep(i, N) {
      string v1, unit1, v2, unit2, eq;
      cin >> v1 >> unit1 >> eq >> v2 >> unit2;
      if (unit1 == unit2) {
        if (v2 == "10^0")
          continue;
        else
          result = false;
        continue;
      }
      // assert(unit1 != unit2);
      if (!result)
        continue;
      // cout << toPower(v1) << " " << unit1 << " = "<< toPower(v2) << " " <<
      // unit2 << endl;
      if (exist.count(unit1) && exist.count(unit2)) {
        rep(i, N) used[i] = false;
        reachable = false;
        move(exist[unit1], exist[unit2]);
        if (reachable) {
          int p1 = toPower(v1);
          int p2 = toPower(v2);
          result = check(unit1, unit2, p2);
          // cout << "result = " << result << endl;
        } else {
          goto Insert;
        }
        continue;
      }

      // cout << "not exists" << endl;
      if (!exist.count(unit1))
        exist[unit1] = index++;
      if (!exist.count(unit2))
        exist[unit2] = index++;
    Insert:;
      int index1 = exist[unit1];
      int index2 = exist[unit2];
      G[index1].push_back(P(unit2, toPower(v2), toPower(v1)));
      G[index2].push_back(P(unit1, toPower(v1), toPower(v2)));
    }
    cout << (result ? "Yes" : "No") << endl;
  }
  return 0;
}

Error: WA

Fixed submission:

#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <map>
#include <set>
#include <sstream>
#include <vector>
#define F first
#define S second
#define inf (1 << 28)
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
using namespace std;

struct P {
  string unit;
  int mpower;
  int upower;
  P(string unit = "$", int upower = -inf, int mpower = -inf)
      : unit(unit), upower(upower), mpower(mpower) {}
};
vector<vector<P>> G(110);
map<string, int> exist;

int toPower(string s) {
  if (s == "1")
    return 0;
  int pos = 0;
  rep(i, s.size()) {
    if (s[i] == '^') {
      pos = i + 1;
      break;
    }
  }
  return (atoi)(s.substr(pos, s.size() - pos).c_str());
}

bool used[110];
int isok; //-1 -> No, 0 => Not yet, 1 -> Ok

void dfs(string now, string target, int power, int target_power) {
  if (isok != 0)
    return;
  if (now == target) {
    isok = (power == target_power ? 1 : -1);
    return;
  }
  int index = exist[now];
  if (used[index])
    return;
  used[index] = true;

  rep(i, G[index].size()) {
    P p = G[index][i];
    int next_index = exist[p.unit];
    if (used[next_index])
      continue;
    dfs(p.unit, target, power + (p.mpower == 0 ? p.upower : -p.mpower),
        target_power);
  }
}

bool check(string u1, string u2, int power) {
  rep(i, 110) used[i] = false;
  isok = 0;

  dfs(u1, u2, 0, power);
  return isok == 1;
}

bool reachable;

void move(int now, int target) {
  if (now == target) {
    reachable = true;
    return;
  }

  if (used[now])
    return;
  used[now] = true;

  rep(i, G[now].size()) {
    if (exist.count(G[now][i].unit) == 0)
      continue;
    assert(exist.count(G[now][i].unit));

    move(exist[G[now][i].unit], target);
  }
}

int main() {
  int N;
  while (cin >> N) {
    assert(N <= 100);
    rep(i, N) G[i].clear();
    int index = 0;
    exist.clear();
    bool result = true;
    rep(i, N) {
      string v1, unit1, v2, unit2, eq;
      cin >> v1 >> unit1 >> eq >> v2 >> unit2;

      if (unit1 == unit2) {
        if (v2 == "10^0")
          continue;
        else
          result = false;
        continue;
      }
      // assert(unit1 != unit2);
      if (!result)
        continue;
      // cout << toPower(v1) << " " << unit1 << " = "<< toPower(v2) << " " <<
      // unit2 << endl;
      if (exist.count(unit1) && exist.count(unit2)) {
        rep(i, N) used[i] = false;
        reachable = false;
        move(exist[unit1], exist[unit2]);
        if (reachable) {
          int p1 = toPower(v1);
          int p2 = toPower(v2);
          result = check(unit1, unit2, p2);
          // cout << "result = " << result << endl;
        } else {
          goto Insert;
        }
        continue;
      }

      // cout << "not exists" << endl;
      if (!exist.count(unit1))
        exist[unit1] = index++;
      if (!exist.count(unit2))
        exist[unit2] = index++;
    Insert:;
      int index1 = exist[unit1];
      int index2 = exist[unit2];
      G[index1].push_back(P(unit2, toPower(v2), toPower(v1)));
      G[index2].push_back(P(unit1, toPower(v1), toPower(v2)));
    }
    cout << (result ? "Yes" : "No") << endl;
  }
  return 0;
}