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


// Membership Management
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1305

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <numeric>
#include <set>
#include <sstream>
#include <vector>

#define ALL(v) (v).begin(), (v).end()
#define REP(i, p, n) for (int i = p; i < (int)(n); ++i)
#define rep(i, n) REP(i, 0, n)
#define dump(a) (cerr << #a << "=" << (a) << endl)
#define DUMP(list)                                                             \\
  cout << "{ ";                                                                \\
  for (auto nth : list) {                                                      \\
    cout << nth << " ";                                                        \\
  }                                                                            \\
  cout << "}" << endl;

using namespace std;

struct Group {
  string name;
  bool checked;
  vector<string> members;
  Group() : name(""), checked(false) {}
  Group(string _name) : name(_name), checked(false) {}

  void join(string member) { members.push_back(member); }
  bool is_member() { return members.size() == 0; }

  bool operator<(const Group &g) const { return name < g.name; }
};

map<string, Group> groups;

vector<string> split(const string &s, char delim) {
  vector<string> elems;
  stringstream ss(s);
  string item;
  while (getline(ss, item, delim)) {
    if (!item.empty()) {
      elems.push_back(item);
    }
  }
  return elems;
}

int dfs(string name) {
  if (groups[name].checked)
    return 0;
  groups[name].checked = true;

  if (groups[name].is_member())
    return 1;

  int visit_total = 0;
  for (string member : groups[name].members) {
    visit_total += dfs(member);
  }
  return visit_total;
}

int main() {
  int N;
  while (cin >> N) {
    if (N == 0)
      break;

    string first_group = "";
    groups.clear();
    for (int nth = 0; nth < N; ++nth) {
      string line;
      cin >> line;
      vector<string> devide = split(line, ':');
      Group group = Group(devide[0]);
      if (nth == 0)
        first_group = devide[0];

      devide[1].erase(--devide[1].end());
      vector<string> members = split(devide[1], ',');
      for (string member : members) {
        group.join(member);
      }

      groups[group.name] = group;
    }

    cout << dfs(first_group) << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:


// Membership Management
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1305

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <numeric>
#include <set>
#include <sstream>
#include <vector>

#define ALL(v) (v).begin(), (v).end()
#define REP(i, p, n) for (int i = p; i < (int)(n); ++i)
#define rep(i, n) REP(i, 0, n)
#define dump(a) (cerr << #a << "=" << (a) << endl)
#define DUMP(list)                                                             \\
  cout << "{ ";                                                                \\
  for (auto nth : list) {                                                      \\
    cout << nth << " ";                                                        \\
  }                                                                            \\
  cout << "}" << endl;

using namespace std;

vector<string> split(const string &s, char delim) {
  vector<string> elems;
  stringstream ss(s);
  string item;
  while (getline(ss, item, delim)) {
    if (!item.empty()) {
      elems.push_back(item);
    }
  }
  return elems;
}

int main() {
  int N;
  while (cin >> N) {
    if (N == 0)
      break;

    string first_group = "";
    map<string, set<string>> groups;
    for (int nth = 0; nth < N; ++nth) {
      string line;
      cin >> line;
      vector<string> devide = split(line, ':');
      string group = devide[0];
      if (nth == 0)
        first_group = group;

      devide[1].erase(--devide[1].end());
      vector<string> members = split(devide[1], ',');
      for (string member : members) {
        groups[group].insert(member);
      }
    }

    while (true) {
      bool is_update = false;
      for (string name : groups[first_group]) {
        if (groups.end() == groups.find(name))
          continue;
        for (string member : groups[name]) {
          groups[first_group].insert(member);
        }
        groups[first_group].erase(name);
        is_update = true;
        break;
      }
      if (!is_update)
        break;
    }

    cout << groups[first_group].size() << endl;
  }
  return 0;
}