Problem p00909 (C++) — buggy submission, verdict: Time Limit Exceeded

#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 <string>
#include <utility>
#include <vector>

using namespace std;

/* constant */

#define MAX_N (100000)

/* typedef */

/* global variables */

int uft[MAX_N + 1], dfs[MAX_N + 1], lvls[MAX_N + 1];

/* subroutines */

int rootd(int k, int &d) {
  int rk = k;
  d = 0;

  while (rk != uft[rk]) {
    d += dfs[rk];
    rk = uft[rk];
  }

  return rk;
}

/* main */

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

    for (int i = 1; i <= n; i++) {
      uft[i] = i;
      dfs[i] = 0;
      lvls[i] = 1;
    }

    for (int i = 0; i < m; i++) {
      char op;
      int a, b;

      cin >> op >> a >> b;

      int ra, rb, da, db;
      ra = rootd(a, da);
      rb = rootd(b, db);

      if (op == '!') {
        int w;
        cin >> w;
        int rd = w + db - da;

        if (ra == rb) {
          if (rd == 0)
            continue;
          cout << "Error" << endl;
          exit(0);
        }

        if (lvls[ra] <= lvls[rb]) {
          uft[ra] = rb;
          dfs[ra] = rd;
          if (lvls[ra] == lvls[rb])
            lvls[rb]++;
        } else {
          uft[rb] = ra;
          dfs[rb] = -rd;
        }
      } else {
        if (ra != rb)
          cout << "UNKNOWN" << endl;
        else {
          int d = da - db;
          cout << d << endl;
        }
      }
    }
  }

  return 0;
}

Error: TLE

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 <string>
#include <utility>
#include <vector>

using namespace std;

/* constant */

#define MAX_N (100000)

/* typedef */

/* global variables */

int uts[MAX_N + 1];
int dfs[MAX_N + 1];

/* subroutines */

int rootd(int k, int &rd) {
  int rk = k;
  rd = 0;

  while (uts[rk]) {
    rd += dfs[rk];
    rk = uts[rk];
  }

  if (rk != k) {
    uts[k] = rk;
    dfs[k] = rd;
  }
  return rk;
}

/* main */

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

    bzero(uts, sizeof(int) * (n + 1));
    bzero(dfs, sizeof(int) * (n + 1));

    for (int i = 0; i < m; i++) {
      char op;
      int a, b;

      cin >> op >> a >> b;

      int ra, rb, da = 0, db = 0;
      ra = rootd(a, da);
      rb = rootd(b, db);

      if (op == '!') {
        int w;
        cin >> w;
        int rd = w + db - da;

        if (ra == rb) {
          if (rd == 0)
            continue;
          cout << "Error" << endl;
          exit(0);
        }

        if (rd >= 0) {
          uts[ra] = rb;
          dfs[ra] = rd;
        } else {
          uts[rb] = ra;
          dfs[rb] = -rd;
        }
      } else {
        if (ra != rb)
          cout << "UNKNOWN" << endl;
        else {
          int d = da - db;
          cout << d << endl;
        }
      }
    }
  }

  return 0;
}