Graph - GitDeveloperKim/DreamEach GitHub Wiki

Graph

์šฉ์–ด ์„ค๋ช…

  • Vertex : ์ •์ 
  • Edge : ๊ฐ„์„ 
  • DAG(Directed Acyclic Graph) : ์‹ธ์ดํด์ด ์—†๋Š” ์œ ํ–ฅ๊ทธ๋ž˜ํ”„

๊ทธ๋ž˜ํ”„ ๊ฐ„์„  ํ‘œํ˜„

  • ์ธ์ ‘ ํ–‰๋ ฌ (Adjacent Matrix) : 2์ฐจ์› ๋ฐฐ์—ด๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ ํ‘œํ˜„, ๋ฉ”๋ชจ๋ฆฌ ๋‚ญ๋น„๊ฐ€ ์‹ฌํ•˜๋‹ค
  • ์ธ์ ‘ ๋ฆฌ์ŠคํŠธ (Adjacent List) : List๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ ๋‚ญ๋น„๊ฐ€ ์ ๋‹ค, ๊ตฌํ˜„์ด ๋ณต์žก
  • ์ธ์ ‘ ์…‹ (Adjacency Set)
  • ๊ฐ„์„ ์˜ ๋ฐฐ์—ด
// list ๋ฐฐ์—ด๋กœ ๊ทธ๋ž˜ํ”„ ๊ฐ„์„  ํ‘œํ˜„ํ•˜๊ธฐ -> ์–ด๋А ํ•œ์ชฝ์ด ๊ณ ์ •๋˜์–ด ์žˆ์„ ๋•Œ ๋งŽ์ด ์‚ฌ์šฉ 
// declare
public static ArrayList< Node > g [];

//init
g = new ArrayList[N+1];
for (int i = 0;i <= N; i++) {
    g[i] = new ArrayList<>();
}

//input
for (int e = 1; e <= E; e++) {
    st = new StringTokenizer(br.readLine());
    int a = Integer.parseInt(st.nextToken());
    int b = Integer.parseInt(st.nextToken());
    int c = Integer.parseInt(st.nextToken());
			
// ๋ฌด๋ฐฉํ–ฅ ๊ทธ๋ž˜ํ”„ 
    g[a].add(new Node(b,c));
    g[b].add(new Node(a,c));
}
// ์ด์ค‘ ๋ฆฌ์ŠคํŠธ๋กœ ๊ทธ๋ž˜ํ”„ ๊ฐ„์„  ํ‘œํ˜„ํ•˜๊ธฐ -> ๋ฉ”๋ชจ๋ฆฌ ์ตœ์ ์œผ๋กœ ๋งŽ์ด ์‚ฌ์šฉ๋œ๋‹ค
// LinkedList ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ˆœ์ฐจ์ ์œผ๋กœ ๊ฒ€์ƒ‰ํ•˜์—ฌ ์ฐพ์•„๊ฐ€๊ธฐ๋•Œ๋ฌธ์— ์‹œ๊ฐ„์ดˆ๊ณผ
// ๋”ฐ๋ผ์„œ ArrayList๋ฅผ ๋งŽ์ด ์‚ฌ์šฉ
// declare
public static ArrayList < ArrayList < Integer > > graph;

// init
graph = new ArrayList< ArrayList < Integer > >();

// input 		
for (int i = 0; i < N+1; i++) {
	graph.add(new ArrayList());
}

// adjacent list example
for (int i = 0; i < M; i++) {
	int []temp = new int[2];
	temp[0] = in.nextInt();          // src
	temp[1] = in.nextInt();          // dst
	graph.get(temp[0]).add(temp[1]); // from src to dst
}
 // ํ•œ ์ •์ ์— ๋ถ™์–ด์žˆ๋Š” ์ธ์ ‘ ํ–‰๋ ฌ ์ˆœํšŒํ• ๋•Œ ์ฐธ์กฐ
for (int[] next : g.get(cur)) { // ๊ฐ„๋‹จํ•˜๊ฒŒ ๋‚˜ํƒ€๋‚ผ์ˆ˜์žˆ๋‹ค 
    // next ....
}

์œ„์ƒ์ •๋ ฌ (Topological Sort) -> O(V+E)

  • ์ˆœํ™˜ํ•˜์ง€ ์•Š๋Š” ๋ฐฉํ–ฅ๊ทธ๋ž˜ํ”„์—์„œ ์‚ฌ์šฉ (DAG: Direct Acyclic Graph)
  • ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋‹ต์ด ์กด์žฌ
  • ๋ชจ๋“  ์›์†Œ๋ฅผ ๋ฐฉ๋ฌธํ•˜๊ธฐ ์ „์— ํ๊ฐ€ ๋นˆ๋‹ค๋ฉด ์‚ฌ์ดํด์ด ์กด์žฌํ•œ๋‹ค๊ณ  ํŒ๋‹จ
  • DFS ๋กœ๋„ ๊ตฌํ˜„ ๊ฐ€๋Šฅ
  • ์œ„์ƒ์ •๋ ฌ ๊ฐœ๋… click
  • ์ง„์ž… ์ฐจ์ˆ˜ (indegree) : ํŠน์ •ํ•œ ๋…ธ๋“œ๋กœ ๋“ค์–ด์˜ค๋Š” ๊ฐ„์„ ์˜ ๊ฐœ์ˆ˜
  • ์ง„์ถœ์ฐจ์ˆ˜ (outdegree) : ํŠน์ •ํ•œ ๋…ธ๋“œ์—์„œ ๋‚˜๊ฐ€๋Š” ๊ฐ„์„ ์˜ ๊ฐœ์ˆ˜
  • ์‹œ๊ฐ„๋ณต์žก๋„ O(V+E)
  1. ์ง„์ž…์ฐจ์ˆ˜๊ฐ€ 0์ธ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ํ์— ๋„ฃ๋Š”๋‹ค
  2. ํ๊ฐ€ ๋นŒ ๋•Œ๊นŒ์ง€ ๋‹ค์Œ์˜ ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•œ๋‹ค
    1. ํ์—์„œ ์›์†Œ๋ฅผ ๊บผ๋‚ด ํ•ด๋‹น ๋…ธ๋“œ์—์„œ ๋‚˜๊ฐ€๋Š” ์„ ์„ ๊ทธ๋ž˜ํ”„์—์„œ ์ œ๊ฑฐํ•œ๋‹ค
    2. ์ƒˆ๋กญ๊ฒŒ ์ง„์ž…์ฐจ์ˆ˜๊ฐ€ 0์ด๋œ ๋…ธ๋“œ๋ฅผ ํ์— ๋„ฃ๋Š”๋‹ค.
  • ๊ฒฐ๊ณผ์ ์œผ๋กœ ๊ฐ ๋…ธ๋“œ๊ฐ€ ํ์— ๋“ค์–ด์˜จ ์ˆœ์„œ๊ฐ€ ์œ„์ƒ ์ •๋ ฌ์„ ์ˆ˜ํ–‰ํ•œ ๊ฒฐ๊ณผ์™€ ๊ฐ™๋‹ค
 
// input 
for (int i = 0; i < M; i++) {
	cin >> a;
	cin >> b;
	++indegree[b]; // ๋‘๋ฒˆ์งธ ๋„์ฐฉ์ง€ ๊ฐฏ์ˆ˜๋ฅผ ์ €์žฅํ•ด๋‘”๋‹ค
	topology[a].push_back(b);  
}
// init 
queue  q;

for (int i = 1; i <= N; i++) {
	if (indegree[i] == 0) {
		q.push(i);					
	}
}

// topology sort 
while (!q.empty()) {
	int temp = q.front();
	q.pop();
	cout << temp << " ";

	for (int i = 0; i < topology[temp].size(); i++) {			
		if (--indegree[topology[temp][i]] == 0) {
			q.push(topology[temp][i]);
		}			
	}
}
  • ๋ฐฑ์ค€ 2252
  • ๋ฐฑ์ค€ 1766
  • ๋งŒ์•ฝ bfs ๋ฅผ ๋Œ์•˜๋Š”๋ฐ indegree๊ฐ’์ด 0์ด ์•„๋‹Œ ๊ฐ’์ด ๋‚จ์•„์žˆ๋‹ค -> ์‚ฌ์ดํด ์ƒ๊ธด๊ฒƒ

for (int i=1; i<=N; i++) {				
    cycle += indegree[i];    // indegree๊ฐ€ 0์ด ์•„๋‹Œ ์ˆ˜๊ฐ€ ๋‚จ์•„์žˆ๋‹ค? -> ์œ„์ƒ์ •๋ ฌ ๋‹ค ๋ชป๋Œ๋ฆฐ๊ฒƒ -> ์‚ฌ์ดํด ์ฒดํฌ 	
}

ํƒ์ƒ‰


public static int bfs () {
        int answer = 0;
	dq = new ArrayDeque<>();
	dq.add(new Node(1,1,input[1][1]));
	visited[1][1] = true;
		
	while (!dq.isEmpty()) {
		Node cur= dq.pollFirst();
		answer = cur.sum;
		
		int nx = cur.x;
		int ny = cur.y;
		
		if (nx == M && ny == N) {
			return answer;
		}
		for (int i = 0; i < 4; i++) {
			nx = cur.x + x[i];
			ny = cur.y + y[i];
			
			if (nx < 1 || nx > M || ny < 1 || ny > N)
				continue;				
			if (visited[ny][nx]) 
				continue;
			
			visited[ny][nx] = true;
			if (input[ny][nx] == 1) {
				dq.addLast(new Node(nx,ny,answer+input[ny][nx]));  // 1์„ ๋งจ ๋’ค์— ๋„ฃ๋Š”๋‹ค
			} else {
				dq.addFirst(new Node(nx,ny,answer+input[ny][nx])); // 0์„ ๋งจ ์•ž์— ๋„ฃ์–ด ๋จผ์ € ๊บผ๋‚ธ๋‹ค
			}
		}
	}
        return answer;
}

์ตœ๋‹จ ๊ฒฝ๋กœ ์ฐพ๊ธฐ

์ตœ๋‹จ ๊ฑฐ๋ฆฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ฌธ์ œ์œ ํ˜•

  • ๋น„๊ฐ€์ค‘ ๊ทธ๋ž˜ํ”„์—์„œ ์ตœ๋‹จ ๊ฒฝ๋กœ
  • ๊ฐ€์ค‘ ๊ทธ๋ž˜ํ”„์—์„œ ์ตœ๋‹จ๊ฒฝ๋กœ

์ตœ๋‹จ ๊ฒฝ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์‘์šฉ

  • ํ•œ๊ณณ์—์„œ ๋‹ค๋ฅธ ๊ณณ์œผ๋กœ ์ด๋™ํ•˜๋Š” ๊ฐ€์žฅ ๋น ๋ฅธ๊ธธ ์ฐพ๊ธฐ
  • ํ•œ ๋„์‹œ์—์„œ ๋‹ค๋ฅธ ๋„์‹œ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ด๊ฑฐ๋‚˜ ์ด๋™ํ•˜๋Š” ๊ฐ€์žฅ ๊ฒฝ์ œ์ ์ธ ๋ฐฉ๋ฒ• ์ฐพ๊ธฐ
  • ๊ฐ„์„ ์˜ ๊ฐ€์ค‘์น˜๊ฐ€ ์žˆ๋Š” ๊ทธ๋ž˜ํ”„์—์„œ ๋‘ ์ •์  ์‚ฌ์ด์˜ ๊ฒฝ๋กœ๋“ค ์ค‘์— ๊ฐ„์„ ์˜ ๊ฐ€์ค‘์น˜์˜ ํ•ฉ์ด ์ตœ์†Œ์ธ ๊ฒฝ๋กœ

1. ๋‹ค์ต์ŠคํŠธ๋ผ (Dijkstra) -> O(ElogV)

๋‚˜๋ฌด์œ„ํ‚ค ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜

  1. ์ถœ๋ฐœ ๋…ธ๋“œ ์„ค์ •
  2. ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ํ…Œ์ด๋ธ” ์ดˆ๊ธฐํ™”(๋ฌดํ•œ๋Œ€)
  3. ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋…ธ๋“œ ์ค‘์—์„œ ์ตœ๋‹จ๊ฑฐ๋ฆฌ๊ฐ€ ๊ฐ€์žฅ ์งง์€ ๋…ธ๋“œ ์„ ํƒ
  4. ํ•ด๋‹น ๋…ธ๋“œ๋ฅผ ๊ฑฐ์ณ ๋‹ค๋ฅธ ๋…ธ๋“œ๋กœ ๊ฐ€๋Š” ๋น„์šฉ์„ ๊ณ„์‚ฐํ•˜์—ฌ ์ตœ๋‹จ๊ฑฐ๋ฆฌ ํ…Œ์ด๋ธ” ๊ฐฑ์‹ 
  5. 3-4 ๊ณผ์ • ๋ฐ˜๋ณต

// ๊ฐ€์ค‘์น˜ ๊ทธ๋ž˜ํ”„ init 
mat = new ArrayList>();		
for (int i = 1 ; i <= n+1; i++) {
	mat.add(new ArrayList<>());
}

// ์„ ์–ธ๋ถ€
d = new int [n+1];      // ๊ฐ ๋…ธ๋“œ์—์„œ ์ตœ๋‹จ๊ฑฐ๋ฆฌ ๊ฐ€์ค‘์น˜ ์ €์žฅ 
path = new int [300];	// ์žกํ•˜์žฅ ๊ฐœ์ˆ˜ <= 200
pq = new PriorityQueue<>((int [] a, int [] b)-> (a[1] > b[1])? 1: -1);	// ๊ฑฐ๋ฆฌ๊ฐ€ ์งง์€ ์ˆœ ์˜ค๋ฆ„์ฐจ์ˆœ 
for (int i = 0; i < m; i++) {
	int src = in.nextInt();
	int dst = in.nextInt();
	int value = in.nextInt();
			
	mat.get(src).add(new int[] {dst, value});	// ์–‘๋ฐฉํ–ฅ ๊ทธ๋ž˜ํ”„์ž„ 
	mat.get(dst).add(new int[] {src, value});	// ๋ฌธ์ œ์—์„œ "๊ทธ ์‚ฌ์ด๋ฅผ ์˜ค๊ฐ€๋Š”๋ฐ ํ•„์š”ํ•œ ์‹œ๊ฐ„" 
}

// ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜ 
public static void dijkstra (int src) {

    pq.add(new int[] {src, 0});	// ํ˜„์žฌ ์œ„์น˜ + ํ•ด๋‹น ์œ„์น˜์—์„œ ๊ฐ€์ค‘์น˜, 0 ์—์„œ ์‹œ์ž‘ 
		
    for (int i = 1; i < n+1; i++) {
	    d[i] = Integer.MAX_VALUE;	// ๊ฐ ์‹œ๋ฐœ์ ๋งˆ๋‹ค ์ดˆ๊ธฐํ™” 
    }
    d[src] = 0;	// ์‹œ์ž‘์  
		
    while (!pq.isEmpty()) {
	    int [] node = pq.poll();	// ํ˜„์žฌ ์‹œ์ž‘์  
	    int cur_node = node[0];
	    int cur_dist = node[1];

            // ์ตœ์ ํ™” 2021-03-26 ์ถ”๊ฐ€ (๋‚˜๋™๋นˆ๋‹˜ ๋‹ค์ต์ŠคํŠธ๋ผ ๊ฐ•์˜ ์ฐธ์กฐ) 
            if (cur_dist > d[cur_node]) // ์ด๋ฏธ ๋ฐฉ๋ฌธ์ด ๋๋‚œ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผ
                continue;
			
	    for (int i = 0; i < mat.get(cur_node).size(); i++) {
	    	    int next_node = mat.get(cur_node).get(i)[0];//ํ˜„์žฌ๋…ธ๋“œ์—์„œ ๋‹ค์Œ ๋…ธ๋“œ๋กœ ์ด๋™ํ• ๋•Œ cost
		    int cost = mat.get(cur_node).get(i)[1];	//ํ˜„์žฌ๋…ธ๋“œ์—์„œ ๋‹ค์Œ ๋…ธ๋“œ๋กœ ์ด๋™ํ• ๋•Œ cost
		    if (d[next_node] > cost + cur_dist) {
			d[next_node] = cost + cur_dist;		//์ตœ๋‹จ๊ฑฐ๋ฆฌ ๋ฐฐ์—ด ์—…๋ฐ์ดํŠธ 
			path [next_node] = cur_node;		// ์ •๋‹ต ์ถœ๋ ฅ์„ ์œ„ next_node ์ตœ๋‹จ๊ฑฐ๋ฆฌ๋ฅผ ์œ„ํ•œ cur_node ์ธ๋ฑ์Šค ์ €์žฅ, ๋์ ์—์„œ ๊ฑฐ๊พธ๋กœ ์ถ”์ ํ•  ์ˆ˜ ์žˆ๋‹ค  
			pq.add(new int[] {next_node, d[next_node]}); // ๋‹ค์Œ๋…ธ๋“œ ํ์— ๋„ฃ๊ธฐ 
		    }
	    }
    }
}

๋ฐฑ์ค€ 1719

2. ๋ฒจ๋งŒ-ํฌ๋“œ (Bellman-Ford) -> O(VE)

  1. ๋ชจ๋“  ๊ฐ„์„ ์ด ์–‘์ˆ˜์ธ ๊ฒฝ์šฐ
  2. ์Œ์ˆ˜ ๊ฐ„์„ ์ด ์žˆ๋Š” ๊ฒฝ์šฐ
    1. ์Œ์ˆ˜ ๊ฐ„์„  ์ˆœํ™˜์€ ์—†๋Š” ๊ฒฝ์šฐ
    2. ์Œ์ˆ˜ ๊ฐ„์„  ์ˆœํ™˜์ด ์žˆ๋Š” ๊ฒฝ์šฐ
  • ์Œ์ˆ˜ ๊ฐ„์„ ์˜ ์ˆœํ™˜์„ ๊ฐ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค
  • ๋ฒจ๋งŒ ํฌ๋“œ์˜ ๊ธฐ๋ณธ ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” O(VE)๋กœ ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ๋น„ํ•ด ๋А๋ฆฝ๋‹ˆ๋‹ค.
  1. ์ถœ๋ฐœ ๋…ธ๋“œ๋ฅผ ์„ค์ •
  2. ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ํ…Œ์ด๋ธ”์„ ์ดˆ๊ธฐํ™”
  3. ๋‹ค์Œ ๊ณผ์ •์„ N-1๋ฒˆ ๋ฐ˜๋ณต
    1. ์ „์ฒด ๊ฐ„์„  E๊ฐœ๋ฅผ ํ•˜๋‚˜์”ฉ ํ™•์ธํ•œ๋‹ค
    2. ๊ฐ ๊ฐ„์„ ์„ ๊ฑฐ์ณ ๋‹ค๋ฅธ ๋…ธ๋“œ๋กœ ๊ฐ€๋Š” ๋น„์šฉ์„ ๊ณ„์‚ฐํ•˜์—ฌ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ํ…Œ์ด๋ธ”์„ ๊ฐฑ์‹ 
  • ๋งŒ์•ฝ ์Œ์ˆ˜ ๊ฐ„์„  ์ˆœํ™˜์ด ๋ฐœ์ƒํ•˜๋Š”์ง€ ์ฒดํฌํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด 3๋ฒˆ์˜ ๊ณผ์ •์„ ํ•œ๋ฒˆ ๋” ์ˆ˜ํ–‰
  • ์ด๋•Œ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ํ…Œ์ด๋ธ”์ด ๊ฐฑ์‹  ๋œ๋‹ค๋ฉด ์Œ์ˆ˜ ๊ฐ„์„  ์ˆœํ™˜์ด ์กด์žฌ

๋ฒจ๋งŒ ํฌ๋“œ ์•Œ๊ณ ๋ฆฌ์ฆ˜ vs ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜

  • ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜
    • ๋งค๋ฒˆ ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋…ธ๋“œ ์ค‘์—์„œ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๊ฐ€ ๊ฐ€์žฅ ์งง์€ ๋…ธ๋“œ๋ฅผ ์„ ํƒ
    • ์Œ์ˆ˜๊ฐ„์„ ์ด ์žˆ์œผ๋ฉด ์‚ฌ์šฉ ๋ถˆ๊ฐ€
  • ๋ฒจ๋งŒ ํฌ๋“œ ์•Œ๊ณ ๋ฆฌ์ฆ˜
    • ๋งค๋ฒˆ ๋ชจ๋“  ๊ฐ„์„ ์„ ์ „๋ถ€ ํ™•์ธ
    • ์Œ์ˆ˜ ๊ฐ„์„  ์ˆœํ™˜ ํƒ์ง€

3. ํ”Œ๋กœ์ด๋“œ-์›Œ์…œ (Floyd-Warshall) -> O(N^3)

  • ๋ชจ๋“  ๋…ธ๋“œ์—์„œ ๋‹ค๋ฅธ ๋ชจ๋“  ๋…ธ๋“œ๊นŒ์ง€์˜ ์ตœ๋‹จ๊ฒฝ๋กœ๋ฅผ ๋ชจ๋‘ ๊ณ„์‚ฐ
  • ๋‹จ๊ณ„๋ณ„๋กœ ๊ฑฐ์ณ๊ฐ€๋Š” ๋…ธ๋“œ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ˆ˜ํ–‰
  • ๋งค ๋‹จ๊ณ„๋งˆ๋‹ค ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋…ธ๋“œ ์ค‘์— ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ฐ–๋Š” ๋…ธ๋“œ๋ฅผ ์ฐพ๋Š” ๊ณผ์ •์ด ํ•„์š”์—†๋‹ค
  • ํ”Œ๋กœ์ด๋“œ ์›Œ์…œ์€ 2์ฐจ์› ํ…Œ์ด๋ธ”์— ์ตœ๋‹จ๊ฑฐ๋ฆฌ ์ •๋ณด๋ฅผ ์ €์žฅ (dp)
  • ํ…Œ์ด๋ธ”์˜ ํฌ๊ธฐ๊ฐ€ 500์„ ๋„˜์–ด๊ฐ€์ง€ ์•Š๋Š”๊ฒฝ์šฐ์— ์‚ฌ์šฉ
  1. ๊ฐ ๋‹จ๊ณ„๋งˆ๋‹ค ํŠน์ •ํ•œ ๋…ธ๋“œ K๋ฅผ ๊ฑฐ์ณ ๊ฐ€๋Š” ๊ฒฝ์šฐ๋ฅผ ํ™•์ธ
  2. a์—์„œ b๋กœ ๊ฐ€๋Š” ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๋ณด๋‹ค a์—์„œ k๋ฅผ ๊ฑฐ์ณ b๋กœ ๊ฐ€๋Š” ๊ฑฐ๋ฆฌ๊ฐ€ ๋” ์งง์€์ง€ ๊ฒ€์‚ฌ
  3. ์ ํ™”์‹ : Dab = min(Dab, Dak+Dkb)

V = in.nextInt();      // ์ •์ 
E = in.nextInt();      // ๊ฐ„์„ 
g = new int[V+1][V+1]; // ๊ฒฝ๋กœ
	
for (int i = 0; i <= V; i++) {
	for (int j = 0; j <=V; j++) {
		g[i][j] = INF; // ์ตœ๋Œ€๊ฐ’์œผ๋กœ ์„ธํŒ… 
	}
}
	
for (int i = 0; i < E; i++) {
	int from = in.nextInt();
	int to = in.nextInt();
	int value = in.nextInt();
	// ๊ฒฝ๋กœ ์ฑ„์šฐ๊ธฐ 
	g[from][to] = value;
}
// ๊ฑฐ์ณ ๊ฐ€๋Š” ๋…ธ๋“œ	
for (int k = 1; k <= V; k++) {
        // ์ถœ๋ฐœ ๋…ธ๋“œ
	for (int i = 1; i <= V; i++) {
                // ๋„์ฐฉ ๋…ธ๋“œ
		for (int j = 1; j <= V; j++) {
			g[i][j] = Math.min(g[i][j], g[i][k]+g[k][j]); // ๊ธฐ์กด ๊ฐ’๊ณผ k๋ฅผ ๊ฑฐ์ณ์„œ ์˜จ ๊ฐ’ ๋น„๊ตํ•ด ์ตœ์†Œ๊ฐ’ ์ž…๋ ฅ, ์ ํ™”์‹ ์•”๊ธฐ!!
		}
	}
}
	
for (int i = 1; i <= V; i++) {
	answer = Math.min(g[i][i], answer);  // ์ถœ๋ ฅ 
}

A* ์•Œ๊ณ ๋ฆฌ์ฆ˜

wiki
blog

์ตœ์†Œ๋น„์šฉ์‹ ์žฅํŠธ๋ฆฌ (MST: Minimum Spanning Tree)

  • ์‹ ์žฅ ํŠธ๋ฆฌ๋Š” ์–ด๋–ค ๊ทธ๋ž˜ํ”„์˜ ๋ถ€๋ถ„ ๊ทธ๋ž˜ํ”„๋กœ ๊ทธ๋ž˜ํ”„์˜ ๋ชจ๋“  ๋…ธ๋“œ์™€ ๊ฐ„์„  ์ผ๋ถ€๋ฅผ ํฌํ•จํ•˜์—ฌ ๋ชจ๋“  ๋…ธ๋“œ๊ฐ„์— ๊ฒฝ๋กœ๊ฐ€ ์กด์žฌํ•˜๋Š”๊ฒƒ
  • ์—ฐ๊ฒฐ๊ทธ๋ž˜ํ”„์ด๋ฉฐ ์‚ฌ์ดํด์ด ์—†๋‹ค
  • ์ตœ์†Œ ์‹ ์žฅ ํŠธ๋ฆฌ๋Š” ์‹ ์žฅ ํŠธ๋ฆฌ ์ค‘ ๊ฐ€์ค‘์น˜๊ฐ€ ๊ฐ€์žฅ ์ž‘์€ ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค
  • Prim -> O(n+mlogm)
  • Kruskal -> O(mlogm)
  • n : ๋…ธ๋“œ / m : ๊ฐ„์„ 

ํฌ๋ฃจ์Šค์ปฌ (Kruskal)

  • ์‚ฌ์ดํด ํŒ๋ณ„ ์•Œ๊ณ ๋ฆฌ์ฆ˜
  1. ๊ฐ ๊ฐ„์„ ์„ ํ•˜๋‚˜์”ฉ ํ™•์ธํ•จ ๋‘ ๋…ธ๋“œ์˜ ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ํ™•์ธ
    1. ๋ฃจํŠธ ๋…ธ๋“œ๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅด๋‹ค๋ฉด ๋‘ ๋…ธ๋“œ์— ๋Œ€ํ•˜์—ฌ ํ•ฉ์ง‘ํ•ฉ(Union) ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰
    2. ๋ฃจํŠธ ๋…ธ๋“œ๊ฐ€ ์„œ๋กœ ๊ฐ™๋‹ค๋ฉด ์‚ฌ์ดํด์ด ๋ฐœ์ƒ
  2. ๊ทธ๋ž˜ํ”„์— ํฌํ•จ๋˜์–ด ์žˆ๋Š” ๋ชจ๋“  ๊ฐ„์„ ์— ๋Œ€ํ•˜์—ฌ 1๋ฒˆ ๊ณผ์ • ๋ฐ˜๋ณต

class Node implements Comparable{
	int src;
	int dst; 
	int weight;
	
	Node (int s, int d, int w) {
		src = s;
		dst = d;
		weight = w;
	}

	@Override
	public int compareTo(Node o) {		
		return this.weight - o.weight;// ๊ฐ€์ค‘์น˜๋กœ ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌ
	}
}

Collections.sort(arr); // ๊ฐ€์ค‘์น˜๋กœ ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌ
		
answer = 0;
for (Node node : arr) {
        // ๋ถ€๋ชจ๋…ธ๋“œ๊ฐ€ ๊ฐ™์€์ง€ ๋ณด๊ณ  
	if (find(node.src) != find(node.dst)) {
		answer += node.weight;
                // ๊ฐ™์ง€์•Š์œผ๋ฉด ํ•ฉ์ณ์ค€๋‹ค
		union(node.src, node.dst);
	}
}
System.out.println(answer);
โš ๏ธ **GitHub.com Fallback** โš ๏ธ