Go: // AOJ ALDS1_11_D: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_11_D

package main

import (
	"bufio"
	"container/list"
	"fmt"
	"os"
	"strconv"
)

var nocolor = -1

type graph struct {
	graph  [][]int
	colors []int
}

func nextInt(sc *bufio.Scanner) int {
	sc.Scan()
	v, _ := strconv.Atoi(sc.Text())
	return v
}

func newGraph(nodeNum int) *graph {
	colors := make([]int, nodeNum)
	g := make([][]int, nodeNum)
	for i := 0; i < nodeNum; i++ {
		g[i] = []int{}
		colors[i] = nocolor
	}

	return &graph{g, colors}
}

func constructGraph(sc *bufio.Scanner) *graph {
	usersNum := nextInt(sc)
	linkNum := nextInt(sc)

	g := newGraph(usersNum)
	for i := 0; i < linkNum; i++ {
		u := nextInt(sc) // node
		l := nextInt(sc) // link node
		// edge each other
		g.graph[u] = append(g.graph[u], l)
		g.graph[l] = append(g.graph[l], u)
	}
	return g
}

func (g *graph) dfs(r, color int) {
	g.colors[r] = color

	stack := list.New()
	stack.PushFront(r)

	for stack.Len() > 0 {
		v := stack.Remove(stack.Front()).(int)
		for _, u := range g.graph[v] {
			if g.colors[u] == nocolor {
				g.colors[u] = color
				stack.PushFront(u)
			}
		}
	}
}

func (g *graph) assignColor() {
	color := 1
	for u := 0; u < len(g.graph); u++ {
		if g.colors[u] == nocolor {
			g.dfs(u, color)
			color++
		}
	}
}

func (g *graph) isLink(s, t int) bool {
	return g.colors[s] == g.colors[t]
}

func main() {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)

	// construct graph and friendly colors
	g := constructGraph(sc)
	g.assignColor()

	// judge link
	q := nextInt(sc)
	for i := 0; i < q; i++ {
		s := nextInt(sc)
		t := nextInt(sc)

		if g.isLink(s, t) {
			fmt.Println("yes")
		} else {
			fmt.Println("no")
		}
	}
}

C++: #include<vector>
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
#include <algorithm>
#include <map>
#include <cmath>
#define INF 100000000000000
using namespace std;
typedef long long llong;

//int isalpha(char ch): ch がアルファベットなら true を返す
//int isdigit(char ch): ch が数字なら true を返す
//int islower(char ch): ch が小文字なら true を返す
//int isupper(char ch): ch が大文字なら true を返す
//int tolower(char ch): ch の小文字を返す
//int toupper(char ch): ch の大文字を返す

//string型
//size()	文字数を返す
//Insert()	（指定した場所に）文字・文字列を挿入する
//erase()	（指定した場所の）文字・文字列を削除する
//clear()	すべての文字を削除する
//substr()	文字列の（指定した）部分文字列を返す
//replace()	（指定した）部分文字列を新しい文字列に置換する
//文字列の比較は、<=や==などを使え
//replace関数を使い、簡単に文字列を置換
//リバース関数：reverse(str.begin(), str.end());
//map<type, type> dict;で宣言
//グラフ理論用変数
//vector<vector<llong> > graph(N);

//ソート
//降順sort(v.begin(), v.end(), std::greater<Type>());

//大文字から小文字へんかん
//w[i] = w[i]-'A'+'a';

//vector
//assignメソッド　引数：サイズ、値
//与えられたサイズと値でvectorを初期化する

void dfs(vector<vector<llong> > &graph, vector<bool> &seen, vector<llong> &color, llong node, llong now_color){
    if(seen[node]){
        return;
    }
    seen[node] = true;
    color[node] = now_color;
    for(int i=0; i<graph[node].size(); i++){
        dfs(graph, seen, color, graph[node][i], now_color);
    }
}

int main(){
    llong n,m;
    llong s,t;
    llong now_color=0;
    scanf("%lld %lld", &n, &m);
    vector<vector<llong> > graph(n);
    vector<bool> seen(n, false);
    vector<llong> color(n, 0);

    for(int i=0; i<m; i++){
        scanf("%lld %lld", &s, &t);
        graph[s].push_back(t);
        graph[t].push_back(s);
    }
    for(int i=0; i<n; i++){
        if(seen[i]){
            continue;
        }
        dfs(graph, seen, color, i, now_color);
        now_color++;
    }
    llong q;
    cin >> q;
    for(int i=0; i<q; i++){
        cin >> s >> t;
        if(color[s]==color[t]){
            cout << "yes" << endl;
        }else{
            cout << "no" << endl;
        }
    }
    return 0;
}

C++: #include <stdio.h>

int m[100000] = {0};

void init() {
	int i;
	for ( i = 0; i < 100000; ++i) {
		m[i] = i;
	}
}

int find(int a) {
	if ( a == m[a]) {
		return a;
	}
	return m[a] = find(m[a]);
}

int friend(int x, int y) {
	if ( find(x) == find(y)) {
		return 1;
	} else {
		return 0;
	}
}

void unit (int x, int y) {
	x = find(x);
	y = find(y);
	
	if ( x == y ) {
		return ;
	}
	m[y] = x;
}

int main() {
	int n, s, t, u, v, i;
	init();
	scanf("%d", &n);
	scanf("%d", &s);
	
	for ( i = 0; i < s; i++) {
		scanf("%d %d", &u, &v);
		unit( u, v);
	}
	
	scanf("%d", &t);
	
	for ( i = 0; i < s; i++) {
		scanf("%d %d", &u, &v);
		if ( friend( u, v) == 1) {
			printf("yes\n");
		} else {
			printf("no\n");
		}
	}
	return 0;
}

C++: #include<iostream>
#include<vector>
#include<queue>
using namespace std;
#define MAX 100000
#define NIL -1

int n, m;
vector<int> V[MAX];
int color[MAX];

void search(int s){
  // init
  queue<int> Q;

  Q.push(s);
  int c = color[s] = s;
  while (!Q.empty()){
    int u = Q.front();
    Q.pop();
    for ( int i = 0; i < V[u].size(); i++){
      if ( color[V[u][i]] == NIL ){
        Q.push(V[u][i]);
        color[V[u][i]] = c;
      }
    }
  }
}

int main(){
  cin >> n >> m;

  int s, t;
  for (int i = 0; i < m; i++ ){
    cin >> s >> t;
    V[s].push_back(t);
    V[t].push_back(s);
  }

  for ( int i = 0; i < n; i++){ color[i] = NIL; }
  for ( int i = 0; i < n; i++){
    if ( color[i] == NIL){
      search(i);
    }
  }

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

  return 0;
}

C++: #include <vector>
#include <cstdio>
class union_find{
	std::vector<int> parent;
public:
	int root(int a){return parent[a]==a?a:(parent[a]=root(parent[a]));}
	union_find(int n):parent(n+1){for(int i=1;i<=n;i++)parent[i]=i;}
	int same(int a,int b){return root(a)==root(b);}
	int unite(int a,int b){
		int x=root(a),y=root(b);//if(x==y)return 0;
		parent[x]=y;
		return 1;
	}
};
int main(){
	int n,m;
	scanf("%d%d",&n,&m);
	union_find uf(n);
	int a,b;
	for(;m--;uf.unite(a,b))scanf("%d%d",&a,&b);
	for(scanf("%d",&m);m--;puts(uf.same(a,b)?"yes":"no"))scanf("%d%d",&a,&b);
}

C++: //
//
//  ad-algoD.cpp - created by us162022
//
#include <iostream>
using namespace std;
int find(int join[],int x){
  if(x==join[x])
    return x;

  return join[x];
}
int main(int argc, char *argv[])
{
  int n,m,join[100000],num[100000],s,t;
  cin >> n >> m;

  for(int i=0; i<n; i++){
    join[i] = i;
    num[i] = 0;
  }

  for(int i=0; i<m; i++){
    cin >> s >> t;
    s = find(join,s);
    t = find(join,t);

    if(s!=t){
      if(num[s] < num[t])
	join[s] = join[t];
      
      else{
	join[t]=join[s];
	if(num[s]==num[t])
	  num[s]++;
      }

    }
  }

  int q;
  cin >> q;

  for(int i=0; i<q; i++){
    cin >> s >> t;

    if(find(join,s)==find(join,t))
      cout << "yes\n";

    else
      cout << "no\n";
  }
}