[白俊]1275号:木を探す親



📌 質問する
根のない木をあげます.ツリーのルートディレクトリが1の場合、各ノードの親ノードを解くプログラムを作成します.
入力
第1行は、ノード数N(2≦N≦100000)を与える.2行目から、ツリーに接続された2点がN−1行に与えられる.
しゅつりょく
1行目からN-1行目まで、各ノードの親ノード番号が2番目のノードから順次出力されます.
入力例1
7
1 6
6 3
3 5
4 1
2 4
4 7
サンプル出力1
4
6
1
3
1
4
入力例2
12
1 2
1 3
2 4
3 5
3 6
4 7
4 8
5 9
5 10
6 11
6 12
サンプル出力2
1
1
2
3
3
4
4
5
5
6
6
📌 プール1(BFS)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.StringTokenizer;

public class Main {

    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringBuilder sb = new StringBuilder();

    static int N;

    static ArrayList< ArrayList<Integer> > list = new ArrayList<>();
    static int[] parents;

    public static void base() throws IOException {
        N = Integer.parseInt(br.readLine());

        for(int i=0; i<=N+1; i++) {
            list.add(new ArrayList<>());
        }

        parents = new int[N+1];
    }

    public static void main(String[] args) throws IOException {
        base();

        for(int i=1; i<N; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine(), " ");

            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());

            list.get(a).add(b);
            list.get(b).add(a);
        }

        int start = 1;

        bfs(start);

        for(int i=2; i<parents.length; i++) {
            System.out.println(parents[i]);
        }
    }

    public static void bfs(int start) {
        LinkedList<Integer> queue = new LinkedList<>();

        queue.offer(start);
        parents[start] = 1;

        while(!queue.isEmpty()) {
            int parent = queue.poll();

            for(int item : list.get(parent)) {
                if(parents[item] == 0) {
                    parents[item] = parent;
                    queue.offer(item);
                }
            }
        }
    }
}
📌 プール2(DFS)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class Main {

    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringBuilder sb = new StringBuilder();

    static int N;
    static ArrayList<Integer>[] list;
    static int[] parents;

    public static void base() throws IOException {
        N = Integer.parseInt(br.readLine());

        list = new ArrayList[N+1];
        for(int i=1; i<=N; i++) {
            list[i] = new ArrayList<Integer>();
        }

        parents = new int[N+1];
    }

    public static void main(String[] args) throws IOException{
        base();

        for(int i=0; i<N-1; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine(), " ");

            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());

            list[a].add(b);
            list[b].add(a);
        }

        dfs(1, 0);

        for(int i=2; i<=N; i++) {
            System.out.println(parents[i]);
        }
    }

    public static void dfs(int start, int parent) {
        parents[start] = parent;
        for(int item : list[start]) {
            if(item != parent) {
                dfs(item, start);
            }
        }
    }
}
📌 整理する
BFS vs DFS
1.Breadth First Search(BFS)/幅を優先的に参照
  • 近接ノードからナビゲーションを開始するアルゴリズム
  • データ構造:キュー
  • 戻るかどうか:X
  • <BFSアルゴリズムの挙動>
  • 「キュー」リソース構造を利用(先入先出方式)
  • 作成アルゴリズム隣接ノードをキューに繰り返し入れる
    =>まず自然に入り、隣接ノードからナビゲート
  • ナビゲーション開始ノードをキューに挿入しアクセス処理
  • ノードをキューから取り出し、そのノードのすべての隣接ノードからアクセスされていないノードをキューに挿入してアクセス処理を行う.
  • 続行できないまで、上記の手順1および2を繰り返します.
  • 2.Depth First Search(DFS)/深度優先ナビゲーション
  • Graphにおける優先深さ探索アルゴリズム
  • データ構造:スタック
  • 戻るかどうか:O
  • 「スタック」リソース構造を利用(後入先出)
  • ナビゲーション開始ノードをスタックに挿入し、アクセス処理を行う.
  • スタックの最上位ノードにアクセスされていない隣接ノードがある場合はスタックに入れてアクセス処理し、アクセスされていない隣接ノードがない場合はスタックから最上位ノードを取り出します
  • 続行できないまで、上記の手順1および2を繰り返します.