Problem p01324 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <iostream>
#include <list>
#include <tuple>
#include <unordered_map>
#include <unordered_set>

int *find(
    std::unordered_map<std::string, std::unordered_map<std::string, int>> *map,
    const std::string &s1, const std::string &s2) {
  auto it1 = map->find(s1);
  if (it1 == map->end())
    return NULL;

  auto it2 = it1->second.find(s2);
  return (it2 == it1->second.end()) ? NULL : &it2->second;
}

bool walk(
    std::unordered_map<std::string, std::unordered_map<std::string, int>> *map,
    const std::tuple<std::string, std::string, int> &t) {
  const std::string &s0 = std::get<0>(t);
  const std::string &s1 = std::get<1>(t);
  int mag1 = std::get<2>(t);

  int *old = find(map, s0, s1);
  if (old == NULL) {
    (*map)[s0][s1] = mag1;
    (*map)[s1][s0] = -mag1;
  } else if (*old != mag1)
    return false;

  std::list<std::tuple<std::string, std::string, int>> next;

  for (auto x : map->at(s0)) {
    const std::string &s2 = x.first;
    int mag2 = x.second;

    if (s1 != s2)
      if (find(map, s1, s2) == NULL)
        next.push_back(std::make_tuple(s1, s2, -mag1 + mag2));
  }

  for (auto x : map->at(s1)) {
    const std::string &s2 = x.first;
    int mag2 = x.second;

    if (s0 != s2)
      if (find(map, s0, s2) == NULL)
        next.push_back(std::make_tuple(s0, s2, mag1 + mag2));
  }

  for (auto t : next)
    if (!walk(map, t))
      return false;

  return true;
}

int main() {
  char line[256];

  while (not std::cin.eof()) {
    int n;
    std::cin >> n;
    if (n == 0)
      break;

    std::list<std::tuple<std::string, std::string, int>> inputs;

    for (int i = 0; i < n; ++i) {
      int x;
      std::string s1, s2;

      std::cin.ignore(2);
      std::cin >> s1;
      std::cin.ignore(6);
      std::cin >> x >> s2;

      inputs.push_back(std::make_tuple(s1, s2, x));
    }

    std::unordered_map<std::string, std::unordered_map<std::string, int>> map;
    bool is_valid(true);

    for (auto x : inputs)
      if (!walk(&map, x)) {
        is_valid = false;
        break;
      }

    std::cout << (is_valid ? "Yes" : "No") << std::endl;
  }

  return 0;
}

Fixed submission:
#include <iostream>
#include <list>
#include <tuple>
#include <unordered_map>
#include <unordered_set>

int *find(
    std::unordered_map<std::string, std::unordered_map<std::string, int>> *map,
    const std::string &s1, const std::string &s2) {
  auto it1 = map->find(s1);
  if (it1 == map->end())
    return NULL;

  auto it2 = it1->second.find(s2);
  return (it2 == it1->second.end()) ? NULL : &it2->second;
}

bool walk(
    std::unordered_map<std::string, std::unordered_map<std::string, int>> *map,
    const std::tuple<std::string, std::string, int> &t) {
  const std::string &s0 = std::get<0>(t);
  const std::string &s1 = std::get<1>(t);
  int mag1 = std::get<2>(t);

  int *old = find(map, s0, s1);
  if (old == NULL) {
    (*map)[s0][s1] = mag1;
    (*map)[s1][s0] = -mag1;
  } else
    return (*old == mag1);

  std::list<std::tuple<std::string, std::string, int>> next;

  for (auto x : map->at(s0)) {
    const std::string &s2 = x.first;
    int mag2 = x.second;

    if (s1 != s2)
      if (find(map, s1, s2) == NULL)
        next.push_back(std::make_tuple(s1, s2, -mag1 + mag2));
  }

  for (auto x : map->at(s1)) {
    const std::string &s2 = x.first;
    int mag2 = x.second;

    if (s0 != s2)
      if (find(map, s0, s2) == NULL)
        next.push_back(std::make_tuple(s0, s2, mag1 + mag2));
  }

  for (auto t : next)
    if (!walk(map, t))
      return false;

  return true;
}

int main() {
  char line[256];

  while (not std::cin.eof()) {
    int n;
    std::cin >> n;
    if (n == 0)
      break;

    std::list<std::tuple<std::string, std::string, int>> inputs;

    for (int i = 0; i < n; ++i) {
      int x;
      std::string s1, s2;

      std::cin.ignore(2);
      std::cin >> s1;
      std::cin.ignore(6);
      std::cin >> x >> s2;

      inputs.push_back(std::make_tuple(s1, s2, x));
    }

    std::unordered_map<std::string, std::unordered_map<std::string, int>> map;
    bool is_valid(true);

    for (auto x : inputs)
      if (!walk(&map, x)) {
        is_valid = false;
        break;
      }

    std::cout << (is_valid ? "Yes" : "No") << std::endl;
  }

  return 0;
}