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

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>

using namespace std;

/* constant */

const int MAX_N = 1000;
const int INF = 1 << 30;

/* typedef */

typedef vector<int> vi;
typedef map<string, int> msi;

struct Tool {
  string name, sup;
  int day1, day2, diff, i, si;

  void print() {
    printf("Tool: %s(%d):%d, %s(%d):%d\\n", name.c_str(), i, day1, sup.c_str(),
           si, day2);
  }
};

/* global variables */

int n;
Tool tools[MAX_N];
msi nhash;

bool used[MAX_N], tmpused[MAX_N];

/* subroutines */

/* main */

int main() {
  for (;;) {
    cin >> n;
    if (n == 0)
      break;

    nhash.clear();
    for (int i = 0; i < n; i++) {
      Tool &ti = tools[i];
      cin >> ti.name >> ti.day1 >> ti.sup >> ti.day2;
      ti.diff = ti.day1 - ti.day2;
      ti.i = i;
      ti.si = -1;
      nhash[ti.name] = i;
    }
    for (int i = 0; i < n; i++) {
      Tool &ti = tools[i];
      ti.si = nhash[ti.sup];
      // ti.print();
    }

    memset(used, false, sizeof(used));

    int minsum = 0;

    // find loops
    for (int i = 0; i < n; i++) {
      Tool &ti = tools[i];
      if (!used[i]) {
        memset(tmpused, false, sizeof(tmpused));
        tmpused[i] = true;
        int j = ti.si;
        for (; !tmpused[j]; j = tools[j].si) {
          if (used[j])
            break;
          tmpused[j] = true;
        }
        if (used[j])
          continue;

        int sumloop = tools[j].day2;
        int mindiff = tools[j].diff;

        used[j] = true;
        for (int k = tools[j].si; k != j; k = tools[k].si) {
          used[k] = true;
          sumloop += tools[k].day2;
          if (mindiff > tools[k].diff)
            mindiff = tools[k].diff;
        }

        minsum += sumloop + mindiff;
      }
    }
    // cout << ln << endl;

    // check leafs
    bool changed = true;
    while (changed) {
      changed = false;

      for (int i = 0; i < n; i++) {
        Tool &ti = tools[i];
        if (!used[i] && used[ti.si]) {
          used[i] = true;
          minsum += ti.day2;
          changed = true;
        }
      }
    }

    cout << minsum << endl;
  }

  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>

using namespace std;

/* constant */

const int MAX_N = 1000;
const int INF = 1 << 30;

/* typedef */

typedef vector<int> vi;
typedef map<string, int> msi;

struct Tool {
  string name, sup;
  int day1, day2, i, si;

  void print() {
    printf("Tool: %s(%d):%d, %s(%d):%d\\n", name.c_str(), i, day1, sup.c_str(),
           si, day2);
  }
};

/* global variables */

int n;
Tool tools[MAX_N];
msi nhash;
bool made[MAX_N];

/* subroutines */

/* main */

int main() {
  for (;;) {
    cin >> n;
    if (n == 0)
      break;

    nhash.clear();
    for (int i = 0; i < n; i++) {
      Tool &ti = tools[i];
      cin >> ti.name >> ti.day1 >> ti.sup >> ti.day2;
      ti.i = i;
      ti.si = -1;
      nhash[ti.name] = i;
    }
    for (int i = 0; i < n; i++) {
      Tool &ti = tools[i];
      ti.si = nhash[ti.sup];
      // ti.print();
    }

    int minday = 0, nu = n;
    memset(made, false, sizeof(made));

    // self dependent
    for (int i = 0; i < n; i++) {
      Tool &ti = tools[i];
      if (i == ti.si) {
        made[i] = true;
        nu--;
        minday += ti.day1;
      }
    }

    // check if dep tool is already made
    bool changed = true;
    while (changed) {
      changed = false;

      for (int i = 0; i < n; i++) {
        Tool &ti = tools[i];
        if (!made[i] && made[ti.si]) {
          made[i] = true;
          nu--;
          minday += ti.day2;
          changed = true;
        }
      }
    }
    // printf("nu=%d, minday=%d\\n", nu, minday);

    // check loops
    for (int i = 0; i < n; i++) {
      Tool &ti = tools[i];
      if (!made[i]) {
        int sumloop = tools[i].day2;
        made[i] = true;
        vi li;
        for (int j = tools[i].si; j != i; j = tools[j].si) {
          made[j] = true;
          sumloop += tools[j].day2;
          li.push_back(j);
        }

        int minloop = INF;
        for (vi::iterator lit = li.begin(); lit != li.end(); lit++) {
          int lsum = sumloop + tools[*lit].day1 - tools[*lit].day2;
          if (minloop > lsum)
            minloop = lsum;
        }
        // printf("  minloop=%d\\n", minloop);

        minday += minloop;
      }
    }

    cout << minday << endl;
  }

  return 0;
}