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

#include <algorithm>
#include <memory.h>
#include <queue>
#include <stdio.h>
#include <vector>

#define UNKNOWN -2000000

using namespace std;

// FILE *in = freopen("input.txt", "r", stdin);
// FILE *out = freopen("output.txt", "w", stdout);

int n, m, M;

vector<vector<pair<int, int>>> data;
bool chk[100001];

int res[100001];
int query[100001][2];
int dist[100001];

struct UnionFind {
  vector<int> par;
  vector<int> rank;
  UnionFind(int n) {
    par = vector<int>(n);
    rank = vector<int>(n);
    for (int i = 0; i < n; i++) {
      par[i] = i;
    }
  }
  int find(int x) {
    if (par[x] == x)
      return x;
    else
      return find(par[x]);
  }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    if (rank[x] < rank[y])
      par[x] = y;
    else {
      par[y] = x;
      if (rank[x] == rank[y])
        rank[x]++;
    }
  }
  inline bool same(int x, int y) { return find(x) == find(y); }
};

void bfs(int a) {
  queue<pair<int, int>> que;
  que.push(make_pair(a, 0));
  chk[a] = true;
  while (!que.empty()) {
    int cur = que.front().first;
    int val = que.front().second;
    que.pop();
    dist[cur] = val;

    for (int i = 0; i < data[cur].size(); i++) {
      if (chk[data[cur][i].first])
        continue;
      chk[data[cur][i].first] = true;
      que.push(make_pair(data[cur][i].first, val + data[cur][i].second));
    }
  }
}

void process() {
  UnionFind uf(n + 1);
  data.clear();
  data.resize(n + 1);
  memset(chk, 0, sizeof(chk));
  memset(res, 0, sizeof(res));
  memset(dist, 0, sizeof(dist));
  M = 0;
  char tt[10];
  int a, b, c;
  for (int k = 0; k < m; k++) {
    scanf("%s%d%d", tt, &a, &b);
    if (tt[0] == '!') {
      scanf("%d", &c);
      if (uf.same(a, b))
        continue;
      data[a].push_back(make_pair(b, c));
      data[b].push_back(make_pair(a, -c));
      uf.unite(a, b);
    } else {
      query[M][0] = a;
      query[M][1] = b;
      if (!uf.same(a, b)) {
        res[M] = UNKNOWN;
      }
      M++;
    }
  }

  for (int i = 1; i <= n; i++) {
    if (!chk[i]) {
      bfs(i);
    }
  }

  for (int i = 0; i < M; i++) {
    if (res[i] == UNKNOWN) {
      printf("UNKNOWN\\n");
    } else {
      printf("%d\\n", dist[query[i][1]] - dist[query[i][0]]);
    }
  }
}

int main() {
  while (true) {
    scanf("%d%d", &n, &m);
    if (n == 0)
      break;
    process();
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <memory.h>
#include <queue>
#include <stdio.h>
#include <vector>

using namespace std;

// FILE *in = freopen("input.txt", "r", stdin);
// FILE *out = freopen("output.txt", "w", stdout);

int n, m;

struct UnionFind {
  vector<int> par;
  vector<int> rank;
  UnionFind(int n) {
    par = vector<int>(n);
    rank = vector<int>(n);
    for (int i = 0; i < n; i++) {
      par[i] = i;
    }
  }
  int find(int x) {
    if (par[x] == x)
      return x;
    else
      return find(par[x]);
  }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    if (rank[x] < rank[y])
      par[x] = y;
    else {
      par[y] = x;
      if (rank[x] == rank[y])
        rank[x]++;
    }
  }
  inline bool same(int x, int y) { return find(x) == find(y); }
};

int bfs(vector<vector<pair<int, int>>> &data, int a, int b) {
  bool chk[100001];
  memset(chk, 0, sizeof(chk));
  queue<pair<int, int>> que;
  que.push(make_pair(a, 0));
  chk[a] = true;
  while (!que.empty()) {
    int cur = que.front().first;
    int val = que.front().second;
    que.pop();
    if (cur == b)
      return val;

    for (int i = 0; i < data[cur].size(); i++) {
      if (chk[data[cur][i].first])
        continue;
      if (data[cur][i].first == b) {
        return val + data[cur][i].second;
      }
      chk[data[cur][i].first] = true;
      que.push(make_pair(data[cur][i].first, val + data[cur][i].second));
    }
  }
  return -1;
}

void process() {
  UnionFind uf(n + 1);
  vector<vector<pair<int, int>>> data(n + 1);
  char tt[10];
  int a, b, c;
  for (int k = 0; k < m; k++) {
    scanf("%s%d%d", tt, &a, &b);
    if (tt[0] == '!') {
      scanf("%d", &c);
      if (uf.same(a, b))
        continue;
      data[a].push_back(make_pair(b, c));
      data[b].push_back(make_pair(a, -c));
      uf.unite(a, b);
    } else {
      if (!uf.same(a, b)) {
        printf("UNKNOWN\\n");
        continue;
      }
      printf("%d\\n", bfs(data, a, b));
    }
  }
}

int main() {
  while (true) {
    scanf("%d%d", &n, &m);
    if (n == 0)
      break;
    process();
  }
  return 0;
}