Language: C++

/**
 * AOJコンテスト：
 *  深さ優先探索：Depth First Search
 *
 *  計算量：O(n + Σk)
 *
 *  入力例：
 *  u k v1 v2 ... vk
 *  (※u：頂点の番号)
 *  (※k：出次数)
 *  (※vi：uに隣接する頂点の番号)
 *
    4
    1 2 2 4
    2 0
    3 0
    4 1 3
 *
 *  出力例：
 *  id d f
 *  (※id：頂点の番号)
 *  (※d：頂点発見時刻)
 *  (※f：頂点完了時刻)
	1 1 8
	2 2 3
	3 5 6
	4 4 7
 */


#include <algorithm>
#include <iostream>
#include <stack>
#include <vector>
using namespace std;


enum VisitColor {
  //未訪問
  WHITE,
  //訪問のみ未完了
  GRAY,
  //完了
  BLACK,
};

static const int kNotExist = -1;
static const int kNotVisit = 0;

void Dfs(const vector<vector<int>>& matrixAdjacency,const int apex_num, vector<pair<int,int>>* time_vector) {
	  //未訪問を白で初期化
	  vector<int> color(apex_num,WHITE);
	  vector<int> current_time(apex_num,0);
	  //経過時間
	  int elapsed_time = 0;
	  int root_id = 0;

	  stack<int> stk;
	  stk.push(root_id);
	  //初訪問時の設定 WHITE~GRAY,発見時刻の登録
	  color[root_id] = GRAY;
	  (*time_vector)[root_id].first = ++elapsed_time;

  while (!stk.empty()) {
    /*
     * スタックに含まれる要素番号の推移
     * 0 - 1 3 - 1 2 - 1 - 空
     */
    int idx_now = stk.top();
    stk.pop();
    color[idx_now] = BLACK;
    (*time_vector)[idx_now].second = ++elapsed_time;

    /*
     * idxNowの行内に隣接先がある場合にpushする
     */
    for (int idx_row = root_id+1; idx_row < apex_num; idx_row++) {
      //隣接先でないもしくは、一度登録したことがある場合は continue
      if ((matrixAdjacency[idx_now][idx_row] == 0) || ((*time_vector)[idx_row].first != kNotVisit)) continue;
      (*time_vector)[idx_row].first = ++elapsed_time;
      color[idx_row] = GRAY;
      stk.push(idx_row);
    }
  }
}

//int GetNextId2(const vector<vector<int>>& matrixAdjacency, vector<int>* current_time,int apex_num,int current_id) {
//  for (int t = (*current_time)[current_id]; t < apex_num; ++t) {
//    (*current_time)[current_id] = t + 1;
//    //隣接先を見受けたらその要素番号を返す
//    if (matrixAdjacency[current_id][t]) return t;
//  }
//  //隣接先がない場合
//  return kNotExist;
//}
int GetAdjacencyId(const vector<vector<int>>& matrixAdjacency, const vector<pair<int,int>>& time_vector,
						const int apex_num, const int current_id, const int root_id) {
	for (int idx_row = root_id + 1; idx_row < apex_num; idx_row++) {
	  //隣接先でないもしくは、一度訪問したことがある場合は continue
	  if ((matrixAdjacency[current_id][idx_row] == 0) || (time_vector[idx_row].first != kNotVisit)) continue;
	  return idx_row;
	}
	//隣接先がない場合
	return kNotExist;
}

void DfsPlus(const vector<vector<int>>& matrixAdjacency, const int apex_num, vector<pair<int,int>>* time_vector) {
  //未訪問を白で初期化
  vector<int> color(apex_num,WHITE);
//  vector<int> current_time(apex_num,0);
  //経過時間
  int elapsed_time = 0;
  int root_id = 0;

  stack<int> stack_id;
  stack_id.push(root_id);

  //初訪問時の設定 WHITE~GRAY,発見時刻の登録
  color[root_id] = GRAY;
  (*time_vector)[root_id].first = ++elapsed_time;

   //未訪問の地（白の場所）を訪れ、GRAY(発見)またはBLACK(完了)に変更する
  while (!stack_id.empty()) {
		/*
		* スタックに含まれる要素番号の推移
		* 0 1 3 2 - 0 1 3 - 0 1 - 0 - 空
		*/
		int idx_now = stack_id.top();
		int idx_now_next = GetAdjacencyId(matrixAdjacency, *time_vector, apex_num, idx_now ,root_id);
	//	int idxNowNext = GetNextId2(matrixAdjacency, &current_time, apex_num, idxNow);
		//子がいない場合
		if (idx_now_next == kNotExist) {
		  stack_id.pop();
		  color[idx_now] = BLACK;
		  //finish_time確定
		  (*time_vector)[idx_now].second = ++elapsed_time;
		}
		//子がまだいる場合
		else if (color[idx_now_next] == WHITE) {
			color[idx_now_next] = GRAY;
			//find_time確定
			(*time_vector)[idx_now_next].first = ++elapsed_time;
			stack_id.push(idx_now_next);
		}
		else{
			//何もしない,この条件は存在するのか？
		}
	}
 }

void CreateMatrixAdjacency(vector<vector<int>>* matrixAdjacency, const int apex_num){
  for (int i = 0; i < apex_num; i++) {
    int apex_id = 0;
    int adj_num = 0;
    cin >> apex_id >> adj_num;
    apex_id--;
    for (int j = 0; j < adj_num; j++) {
      int adj_id = 0;
      cin >> adj_id;
      adj_id--;
      (*matrixAdjacency)[apex_id][adj_id] = 1;
    }
  }
}

int main() {

  int apex_num;
  cin >> apex_num;
  vector<vector<int>> matrixAdjacency(apex_num, vector<int>(apex_num));

	CreateMatrixAdjacency(&matrixAdjacency,apex_num);

  //first:find_time, second:finish_time
  vector<pair<int,int>> time_vector(apex_num);
  DfsPlus(matrixAdjacency,apex_num, &time_vector);

  for (int i = 0; i < apex_num; i++) {
    cout << i + 1 << " " << time_vector[i].first << " " << time_vector[i].second << endl;
  }
  return 0;
}
/**
 *  AOJコンテスト：
 *  幅優先探索：Breadth First Search
 *
 *  計算量：O(apex_num + Σk)
 *
 *  入力例：
 *  u k v1 v2 ... vk
 *  (※u：頂点の番号)
 *  (※k：出次数)
 *  (※vi：uに隣接する頂点の番号)
 *
    4
    1 2 2 4
    2 0
    3 0
    4 1 3
 *
 *  出力例：
 *  id d
 *  (※id：頂点の番号)
 *  (※d：頂点1からその頂点までの距離)
    1 0
    2 1
    3 2
    4 1
 */


#include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
#include <stack>
using namespace std;

//未登録
static const int kNotRegister = -1;

void Bfs(const vector<vector<int>>& matrixAdjacency, const int apex_num, const int idx_root, vector<int>* dst) {
  queue<int> que;
  que.push(idx_root);
  (*dst)[idx_root] = 0;

  while (!que.empty()) {
    /*
     * キューに含まれる要素番号の推移
     * 0 - 1 3 - 3 - 2 - 空
     */
    int idx_now = que.front();
    que.pop();
    /*
     * idxNowの行内に隣接先がある場合にpushする
     */
    for (int idx_row = idx_root+1; idx_row < apex_num; idx_row++) {
      //隣接先でないもしくは、一度登録したことがある場合は continue
      if ((matrixAdjacency[idx_now][idx_row] == 0) || ((*dst)[idx_row] != kNotRegister)) continue;
      (*dst)[idx_row] = (*dst)[idx_now] + 1;
      que.push(idx_row);
    }
  }
}
void Dfs(const vector<vector<int>>& matrixAdjacency, const int apex_num, const int idx_root, vector<int>* dst) {
  stack<int> stk;
  stk.push(idx_root);
  (*dst)[idx_root] = 0;

  while (!stk.empty()) {
    /*
     * スタックに含まれる要素番号の推移
     * 0 - 1 3 - 1 2 - 1 - 空
     */
    int idx_now = stk.top();
    stk.pop();
    /*
     * idxNowの行内に隣接先がある場合にpushする
     */
    for (int idx_row = idx_root+1; idx_row < apex_num; idx_row++) {
      //隣接先でないもしくは、一度登録したことがある場合は continue
      if ((matrixAdjacency[idx_now][idx_row] == 0) || ((*dst)[idx_row] != kNotRegister)) continue;
      (*dst)[idx_row] = (*dst)[idx_now] + 1;
      stk.push(idx_row);
    }
  }
}

/**
 * matrixAdjacency
 * [0]:0 1 0 1
 * [1]:0 0 1 1
 * [2]:0 0 0 0
 * [3]:0 0 0 0
 *
 */
void CreateMatrixAdjacency(vector<vector<int>>* matrixAdjacency, const int apex_num){
	int apex_id, adj_num, adj_id;
  for (int i = 0; i < apex_num; i++) {
    cin >> apex_id >> adj_num;
    apex_id--;
    for (int j = 0; j < adj_num; j++) {
      cin >> adj_id;
      adj_id--;
      (*matrixAdjacency)[apex_id][adj_id] = 1;
    }
  }
}

int main() {
	int apex_num;
  cin >> apex_num;
  /*隣接行列作成*/
  vector<vector<int> > matrixAdjacency(apex_num, vector<int>(apex_num));
  /*隣接行列作成*/
  CreateMatrixAdjacency(&matrixAdjacency, apex_num);

  vector<int> dst(apex_num, kNotRegister);
  Bfs(matrixAdjacency,apex_num,0, &dst);
//  Dfs(matrixAdjacency,apex_num,0, &dst);

  for (int i = 0; i < apex_num; i++) {
    cout << i + 1 << " ";
    if(dst[i] == kNotRegister){
      cout << -1 << endl;
    }
    else{
      cout << dst[i] << endl;
    }
  }

  return 0;
}
/**
 *  無向グラフ：双方に行き来可能
 *  深さ優先探索：DFS
 *
    ある頂点から深さ優先探索、もしくは幅優先探索を行い到達できた全ての頂点を同じグループに入れます。
    これを未到達の頂点がなくなるまで行い、sとtが同じグループに入っているかどうかを調べます
 *
 *  計算量：O(n + m)
 *
 *  入力例：
 *  n  m
 *  s1  t1
 *  sm  tm
 *  q
 *  s1  t1
 *  sq  tq
 *
 *  (※n：ユーザ数)
 *  (※m：友達関係の数)
 *  (※s1 t1：s1とt1が友達である)
 *  (※q：質問数)
 *  (※s1 t1：s1からt1にたどり着けるか)
 *
    10 9
    0 1
    0 2
    3 4
    5 7
    5 6
    6 7
    6 8
    7 8
    8 9
    3
    0 1
    5 9
    1 3
 *
 *  出力例：各質問に対してたどり着けるかどうか(yes/no)
 *
 *
 */
#include <algorithm>
#include <iostream>
#include <vector>
#include <stack>

using namespace std;
//未登録
static const int kNotColor = -1;

//void Dfs(int idxNow, int userNum) {
//  for (int i = 0; i < userNum; i++) color[i] = NOT_COLOR;
//  int colorId = 1;
//
//  for (int idxNow = 0; idxNow < userNum; idxNow++) {
//    if (color[idxNow] == NOT_COLOR) {
//	  stack<int> stk;
//	  stk.push(idxNow);
//	  color[idxNow] = colorId;
//	  while (!stk.empty()) {
//		int idxNow = stk.top();
//		stk.pop();
//		for (int i = 0; i < (int)connectionUser[idxNow].size(); i++) {
//		  int friendId = connectionUser[idxNow][i];
//		  if (color[friendId] == NOT_COLOR) {
//			color[friendId] = colorId;
//			stk.push(friendId);
//		  }
//		}
//	  }
//	  colorId++;
//	 }
//  }
//}
void dfs(const vector<vector<int>>& connection_user, const int idx_now,
		const int group_id, vector<int>* group) {
	stack<int> stk;
	stk.push(idx_now);
	(*group)[idx_now] = group_id;
	while (!stk.empty()) {
		int idx_now = stk.top();
		stk.pop();
		for (int i = 0; i < (int) connection_user[idx_now].size(); i++) {
			int friend_id = connection_user[idx_now][i];
			if ((*group)[friend_id] == kNotColor) {
				(*group)[friend_id] = group_id;
				stk.push(friend_id);
			}
		}
	}
}
void assignColor(const vector<vector<int>>& connection_user, const int user_num, vector<int>* group) {
  //色の未訪問（白）として初期化
  for (int i = 0; i < user_num; i++) (*group)[i] = kNotColor;
  int group_id = 1;
  for (int idxNow = 0; idxNow < user_num; idxNow++) {
    if ((*group)[idxNow] == kNotColor) {
      dfs(connection_user,idxNow, group_id, group);
      group_id++;
    }
  }
}

int main() {
  int user_num = 0;
  int friend_num = 0;
  cin >> user_num >> friend_num;
  /*  ex)中身(各ユーザーのつながり)
   *  [0]：1 2
   *  [1]：0
   *  [2]：0
   *  [3]：4
   *  [4]：3
   *  [5]：7 6
   *  [6]：5 7 8
   *  [7]：5 6 8
   *  [8]：6 7 9
   *  [9]：8
   */
  vector<vector<int>> connection_user(user_num,vector<int>(0));
  for (int i = 0; i < friend_num; i++) {
    int s = 0;
	int t = 0;
    cin >> s >> t;
    connection_user[s].push_back(t);
    connection_user[t].push_back(s);
  }
  /*  colorの中身(グループ分け)
   *  [0]：1
   *  [1]：1
   *  [2]：1
   *  [3]：2
   *  [4]：2
   *  [5]：3
   *  [6]：3
   *  [7]：3
   *  [8]：3
   *  [9]：3
   */
  vector<int> group(user_num);
  assignColor(connection_user,user_num , &group);
//  Dfs(0,userNum);

  int questionNum = 0;
  cin >> questionNum;
  for (int i = 0; i < questionNum; i++) {
    int s = 0;
	int t = 0;
    cin >> s >> t;
    if (group[s] == group[t]) {
      cout << "yes" << endl;
    } else {
      cout << "no" << endl;
    }
  }

  return 0;
}


Compiler output:
a.cc:277:6: error: redefinition of 'void CreateMatrixAdjacency(std::vector<std::vector<int> >*, int)'
  277 | void CreateMatrixAdjacency(vector<vector<int>>* matrixAdjacency, const int apex_num){
      |      ^~~~~~~~~~~~~~~~~~~~~
a.cc:151:6: note: 'void CreateMatrixAdjacency(std::vector<std::vector<int> >*, int)' previously defined here
  151 | void CreateMatrixAdjacency(vector<vector<int>>* matrixAdjacency, const int apex_num){
      |      ^~~~~~~~~~~~~~~~~~~~~
a.cc:290:5: error: redefinition of 'int main()'
  290 | int main() {
      |     ^~~~
a.cc:166:5: note: 'int main()' previously defined here
  166 | int main() {
      |     ^~~~
a.cc:418:5: error: redefinition of 'int main()'
  418 | int main() {
      |     ^~~~
a.cc:166:5: note: 'int main()' previously defined here
  166 | int main() {
      |     ^~~~