Problem p00715 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <map>
#include <stdio.h>
#include <string>
#include <vector>
using namespace std;
char in[50];
char L[50];
char R[50];
int p[500];
int q[500];
int UF[500];
int FIND(int a) {
  if (UF[a] < 0)
    return a;
  return UF[a] = FIND(UF[a]);
}
void UNION(int a, int b) {
  a = FIND(a);
  b = FIND(b);
  if (a == b)
    return;
  UF[a] += UF[b];
  UF[b] = a;
}
int g[310][310];
int g2[310][310];
int main() {
  int a;
  while (scanf("%d", &a), a) {
    map<string, int> m;
    int n = 0;
    for (int i = 0; i < 500; i++)
      UF[i] = -1;
    for (int i = 0; i < a; i++) {
      scanf("%s", in);
      int at = 0;
      int j;
      for (j = 0; in[j] != '-'; j++) {
        L[at] = in[j];
        at++;
      }
      L[at] = 0;
      at = 0;
      j++;
      for (; in[j]; j++) {
        R[at] = in[j];
        at++;
      }
      R[at] = 0;
      //		printf("%s %s\n",L,R);
      string l = L;
      string r = R;
      if (m.count(l))
        p[i] = m[l];
      else {
        m[l] = n;
        p[i] = n++;
      }
      if (m.count(r)) {
        q[i] = m[r];
      } else {
        m[r] = n;
        q[i] = n++;
      }
    }
    for (int i = 0; i < n; i++)
      for (int j = 0; j < n; j++)
        g[i][j] = 0;
    for (int i = 0; i < a; i++)
      g[p[i]][q[i]] = 1;
    for (int i = 0; i < n; i++)
      for (int j = 0; j < n; j++)
        g2[i][j] = 0;
    for (int i = 0; i < n; i++)
      g2[i][i] = 1;
    for (int i = 0; i < a; i++)
      g2[p[i]][q[i]] = 1;
    for (int i = 0; i < n; i++) {
      for (int j = i + 1; j < n; j++) {
        bool ok1 = false;
        bool ok2 = true;
        for (int k = 0; k < n; k++) {
          if (g[i][k] && g[j][k])
            ok1 = true;
          if (g[k][i] && g[k][j])
            ok1 = true;
          if (g[i][k] && g[k][j])
            ok2 = false;
          if (g[j][k] && g[k][i])
            ok2 = false;
        }
        if (ok1 && ok2)
          g2[i][j] = g2[j][i] = 1;
      }
    }
    for (int k = 0; k < n; k++)
      for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
          g2[i][j] |= g2[i][k] & g2[k][j];
    printf("%d\n", n);
    for (int i = 0; i < a; i++) {
      UNION(p[i] * 2, q[i] * 2 + 1);
      UNION(p[i] * 2 + 1, q[i] * 2);
    }
    int b;
    scanf("%d", &b);
    for (int i = 0; i < b; i++) {
      scanf("%s", in);
      int at = 0;
      int j;
      for (j = 0; in[j] != '-'; j++) {
        L[at] = in[j];
        at++;
      }
      L[at] = 0;
      at = 0;
      j++;
      for (; in[j]; j++) {
        R[at] = in[j];
        at++;
      }
      R[at] = 0;
      string l = L;
      string r = R;
      if (!m.count(l) || !m.count(r)) {
        printf("NO\n");
        continue;
      }
      int P = m[l];
      int Q = m[r];
      if (FIND(P * 2) != FIND(Q * 2 + 1) || FIND(P * 2 + 1) != FIND(Q * 2)) {
        printf("NO\n");
        continue;
      }
      if (g2[P][Q])
        printf("YES\n");
      else
        printf("NO\n");
    }
  }
}

Fixed submission:
#include <algorithm>
#include <map>
#include <stdio.h>
#include <string>
#include <vector>
using namespace std;
char in[50];
char L[50];
char R[50];
int p[5100];
int q[5100];
int UF[500];
int FIND(int a) {
  if (UF[a] < 0)
    return a;
  return UF[a] = FIND(UF[a]);
}
void UNION(int a, int b) {
  a = FIND(a);
  b = FIND(b);
  if (a == b)
    return;
  UF[a] += UF[b];
  UF[b] = a;
}
int g[310][310];
int g2[310][310];
int main() {
  int a;
  while (scanf("%d", &a), a) {
    map<string, int> m;
    int n = 0;
    for (int i = 0; i < 500; i++)
      UF[i] = -1;
    for (int i = 0; i < a; i++) {
      scanf("%s", in);
      int at = 0;
      int j;
      for (j = 0; in[j] != '-'; j++) {
        L[at] = in[j];
        at++;
      }
      L[at] = 0;
      at = 0;
      j++;
      for (; in[j]; j++) {
        R[at] = in[j];
        at++;
      }
      R[at] = 0;
      //		printf("%s %s\n",L,R);
      string l = L;
      string r = R;
      if (m.count(l))
        p[i] = m[l];
      else {
        m[l] = n;
        p[i] = n++;
      }
      if (m.count(r)) {
        q[i] = m[r];
      } else {
        m[r] = n;
        q[i] = n++;
      }
    }
    for (int i = 0; i < n; i++)
      for (int j = 0; j < n; j++)
        g[i][j] = 0;
    for (int i = 0; i < a; i++)
      g[p[i]][q[i]] = 1;
    for (int i = 0; i < n; i++)
      for (int j = 0; j < n; j++)
        g2[i][j] = 0;
    for (int i = 0; i < n; i++)
      g2[i][i] = 1;
    for (int i = 0; i < a; i++)
      g2[p[i]][q[i]] = 1;
    for (int i = 0; i < n; i++) {
      for (int j = i + 1; j < n; j++) {
        bool ok1 = false;
        bool ok2 = true;
        for (int k = 0; k < n; k++) {
          if (g[i][k] && g[j][k])
            ok1 = true;
          if (g[k][i] && g[k][j])
            ok1 = true;
          if (g[i][k] && g[k][j])
            ok2 = false;
          if (g[j][k] && g[k][i])
            ok2 = false;
        }
        if (ok1 && ok2)
          g2[i][j] = g2[j][i] = 1;
      }
    }
    for (int k = 0; k < n; k++)
      for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
          g2[i][j] |= g2[i][k] & g2[k][j];
    printf("%d\n", n);
    for (int i = 0; i < a; i++) {
      UNION(p[i] * 2, q[i] * 2 + 1);
      UNION(p[i] * 2 + 1, q[i] * 2);
    }
    int b;
    scanf("%d", &b);
    for (int i = 0; i < b; i++) {
      scanf("%s", in);
      int at = 0;
      int j;
      for (j = 0; in[j] != '-'; j++) {
        L[at] = in[j];
        at++;
      }
      L[at] = 0;
      at = 0;
      j++;
      for (; in[j]; j++) {
        R[at] = in[j];
        at++;
      }
      R[at] = 0;
      string l = L;
      string r = R;
      if (!m.count(l) || !m.count(r)) {
        printf("NO\n");
        continue;
      }
      int P = m[l];
      int Q = m[r];
      if (FIND(P * 2) != FIND(Q * 2 + 1) || FIND(P * 2 + 1) != FIND(Q * 2)) {
        printf("NO\n");
        continue;
      }
      if (g2[P][Q])
        printf("YES\n");
      else
        printf("NO\n");
    }
  }
}