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

#include <iostream>
#include <map>
#include <set>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

typedef vector<vector<int>> Graph;

#define N 3000

int cnt = 0;
bool vis[N];
map<string, int> D;
map<int, string> revD;
set<string> Groups;

void dfs(const Graph &G, string cur) {
  // cout << st << ' ' << revD[st] << ' ' << G[st].size() << endl;
  int v = D[cur];
  if (Groups.find(cur) == Groups.end())
    ++cnt;
  for (int i = 0; i < (int)G[v].size(); ++i) {
    if (!vis[G[v][i]]) {
      vis[G[v][i]] = true;
      dfs(G, revD[G[v][i]]);
    }
  }
}

int main() {
  while (true) {
    int id = 0;
    Graph G(N);
    int n;

    D.clear();
    revD.clear();
    Groups.clear();
    cnt = 0;
    fill(vis, vis + N, false);
    cin >> n;
    if (n == 0)
      break;

    string g1;
    for (int i = 0; i < n; ++i) {
      string line;
      cin >> line;
      for (int j = 0; j < (int)line.length(); ++j) {
        if (line[j] == ':')
          line[j] = ' ';
        if (line[j] == ',')
          line[j] = ' ';
        if (line[j] == '.')
          line[j] = ' ';
      }
      istringstream iss(line);
      string group;

      iss >> group;
      // cout << "Group : " << group << endl;

      D[group] = id;
      revD[id] = group;
      Groups.insert(group);
      ++id;

      if (i == 0)
        g1 = group;
      while (iss) {
        string tmp;
        iss >> tmp;
        if (tmp.length() > 0) {
          if (D.find(tmp) == D.end()) {
            D[tmp] = id;
            revD[id] = tmp;
            ++id;
          }
          G[D[group]].push_back(D[tmp]);
          // cout << "Added : " << D[tmp] << ' ' << revD[id] << endl;
        }
      }

      // cout << G[D[group]].size() << endl;
    }

    dfs(G, g1);
    cout << cnt << endl;
    // return 0;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <iostream>
#include <map>
#include <set>
#include <sstream>
#include <string>

using namespace std;

int main() {
  while (true) {
    map<string, set<string>> G;
    int n;
    cin >> n;
    if (n == 0)
      break;
    string g1;
    for (int i = 0; i < n; ++i) {
      string line;
      cin >> line;
      for (int j = 0; j < (int)line.length(); ++j) {
        if (line[j] == ':')
          line[j] = ' ';
        if (line[j] == ',')
          line[j] = ' ';
        if (line[j] == '.')
          line[j] = ' ';
      }
      istringstream iss(line);
      string group;
      iss >> group;
      if (i == 0)
        g1 = group;
      while (iss) {
        string tmp;
        iss >> tmp;
        if (tmp.length() > 0)
          G[group].insert(tmp);
      }
    }

    set<string> res;
    res.insert(g1);

    // continue;

  retry:;
    while (true) {
      bool find = false;
      for (set<string>::iterator it = res.begin(); it != res.end(); ++it) {
        if (G.find(*it) != G.end()) {
          find = true;
          set<string> S = G.find(*it)->second;
          res.erase(it);
          for (set<string>::iterator it2 = S.begin(); it2 != S.end(); ++it2) {
            res.insert(*it2);
          }
          goto retry;
        }
      }
      if (!find)
        break;
    }

    cout << res.size() << endl;
  }
  return 0;
}