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

#include <set>
#include <stdio.h>
#define MAX_USER (100000)

typedef std::set<long> Circle;

void merge_circle(Circle **circleinfo, long uid1, long uid2) {
  Circle *src;
  Circle *dst;
  if (circleinfo[uid1]->size() < circleinfo[uid2]->size()) {
    src = circleinfo[uid1];
    dst = circleinfo[uid2];
  } else {
    src = circleinfo[uid2];
    dst = circleinfo[uid1];
  }

  Circle::const_iterator itr;
  for (itr = src->begin(); itr != src->end(); itr++) {
    circleinfo[*itr] = dst;
    dst->insert(*itr);
  }
}

void add_member(Circle **circleinfo, long uid1, long uid2) {
  if (circleinfo[uid1] == 0 && circleinfo[uid2] == 0) {
    // create new circle
    Circle *entry = new Circle;
    entry->insert(uid1);
    entry->insert(uid2);

    circleinfo[uid1] = entry;
    circleinfo[uid2] = entry;
  } else if (circleinfo[uid1] != 0 && circleinfo[uid2] == 0) {
    circleinfo[uid1]->insert(uid2);
    circleinfo[uid2] = circleinfo[uid1];
  } else if (circleinfo[uid1] == 0 && circleinfo[uid2] != 0) {
    circleinfo[uid2]->insert(uid1);
    circleinfo[uid1] = circleinfo[uid2];
  } else {
    if (circleinfo[uid1] != circleinfo[uid2]) {
      merge_circle(circleinfo, uid1, uid2);
    }
  }
}

int main(int argc, char **argv) {

  // read setting
  long user_count;
  long friendship_count;
  scanf("%ld %ld", &user_count, &friendship_count);

  // initialize
  Circle **user_info = new Circle *[user_count];
  for (long i = 0; i < user_count; i++) {
    user_info[i] = 0;
  }

  // read user friendship
  for (long i = 0; i < friendship_count; i++) {
    long uid1;
    long uid2;
    scanf("%ld %ld", &uid1, &uid2);

    add_member(user_info, uid1, uid2);
  }

  // read number of question
  long question_count;
  scanf("%ld", &question_count);

  // process question
  for (long i = 0; i < question_count; i++) {
    long uid1;
    long uid2;
    scanf("%ld %ld", &uid1, &uid2);

    if (user_info[uid1] == user_info[uid2] && user_info[uid1] != 0) {
      printf("yes\\n");
    } else {
      printf("no\\n");
    }
  }

  delete[] user_info;
  return 0;
}

Error: TLE

Fixed submission:

#include <stdio.h>

#define MAX_USER (100000)

/*

1)initial state

        0    1    2    3    4    5...

2)create friendship
        friend: 0 and 1
        friend: 2 and 3

        0    2    4
    |    |
        1    3

3)and more
        friend: 2 and 4

        0       2      5
        |      / \\
        1     3---4

*/

struct UserInfo {
  long uid;
  UserInfo *next;
  UserInfo *prev;
};

int examine_friendship(const UserInfo *user_info, long uid1, long uid2) {
  UserInfo *uid_ptr = user_info[uid1].next;

  while (uid_ptr->uid != uid1) {
    if (uid_ptr->uid == uid2) {
      return 1;
    }
    uid_ptr = uid_ptr->next;
  }
  return 0;
}

int main(int argc, char **argv) {
  // read setting
  long user_count;
  long friendship_count;
  scanf("%ld %ld", &user_count, &friendship_count);

  // initialize
  UserInfo *user_info = new UserInfo[user_count];
  for (long i = 0; i < user_count; i++) {
    user_info[i].uid = i;
    user_info[i].next = &user_info[i];
    user_info[i].prev = &user_info[i];
  }

  // read user friendship
  for (long i = 0; i < friendship_count; i++) {
    long uid1;
    long uid2;
    scanf("%ld %ld", &uid1, &uid2);

    if (!examine_friendship(user_info, uid1, uid2)) {
      // update internal data
      UserInfo *uid1_ptr = &user_info[uid1];
      UserInfo *uid2_ptr = &user_info[uid2];
      UserInfo *uid1_prev_ptr = uid1_ptr->prev;
      UserInfo *uid2_next_ptr = uid2_ptr->next;

      uid1_ptr->prev = uid2_ptr;
      uid2_ptr->next = uid1_ptr;

      uid1_prev_ptr->next = uid2_next_ptr;
      uid2_next_ptr->prev = uid1_prev_ptr;
    }
  }

  // read number of question
  long question_count;
  scanf("%ld", &question_count);

  // process question
  for (long i = 0; i < question_count; i++) {
    long uid1;
    long uid2;
    scanf("%ld %ld", &uid1, &uid2);

    if (examine_friendship(user_info, uid1, uid2)) {
      printf("yes\\n");
    } else {
      printf("no\\n");
    }
  }

  delete[] user_info;
  return 0;
}