www.acmicpc.net/problem/11404

 

11404번: 플로이드

첫째 줄에 도시의 개수 n(1 ≤ n ≤ 100)이 주어지고 둘째 줄에는 버스의 개수 m(1 ≤ m ≤ 100,000)이 주어진다. 그리고 셋째 줄부터 m+2줄까지 다음과 같은 버스의 정보가 주어진다. 먼저 처음에는 그

www.acmicpc.net

 

1. 풀이방법

 

 

- 문제를 읽다보면 문제에서는 버스, 즉 간선(단방향)이 비용(가중치)를 각각 가지고 있다.

 

 

- (->BFS로는 구할 수 없겠구나 ! 라는 생각)

 

 

- 다익스트라 또는 플로이드 워셜 (대표적)

 

 

- 근데 출력을 보니 모든 도시에서 자신을 제외한 모든 점까지의 최단거리를 출력하는 문제 (자신 또는 못가는 경우 0 )

 

 

- (-> 플로이드 워셜 ! )

 

 

 

 

 

2. 주의사항

 

 

- 구현 시 도시사이의 거리를 입력 받기전 가장 큰 값으로 초기화 해줘야 하는데 COST가 100,000을 넘지 않는 다는 말을

 

 

- 보고 100001으로 정의해두었다가(INF) 계쏙 98퍼에서 오류가 뜨길래...생각해보니...

 

 

- 거쳐서 가는경우 100,000을 그냥 넘을 수 있다는 것......!!! 주의주의.... 그래서 그냥 987654321로 초기화 하였다

 

 

 

 

3. 나의코드

 

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#define INF 987654321

int n, m;
int CityToCity[101][101];

void inputs() { //입력함수
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) { //초기화
			if (i == j) continue;
			CityToCity[i][j]=INF;
		}
	}
	int start, end, cost;
	for (int i = 0; i < m; i++) {
		cin >> start >> end >> cost;
		if (CityToCity[start][end] > cost) {
			CityToCity[start][end] = cost;
		}
	}
}

void Searchmin() {
	for (int a = 1; a <= n; a++) {
		for (int b = 1; b <= n; b++) {
			for (int c = 1; c <= n; c++) {
				if (CityToCity[b][a] != INF && CityToCity[a][c] != INF) { //거쳐서 갈 수 있는 경우
					CityToCity[b][c] = min(CityToCity[b][c], (CityToCity[b][a] + CityToCity[a][c]));
				}
			}
		}
	}
}
void outputs() { //출력함수
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			if (CityToCity[i][j] == INF||i==j)  cout << 0 << " "; 
			else cout << CityToCity[i][j] << " ";
		}
		cout << "\n";
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
	inputs();
	Searchmin();
	outputs();
	return 0;
}

'알고리즘 문제풀이 > DFS와 BFS' 카테고리의 다른 글

백준 15684 [C++]  (0) 2020.12.09
백준 15683 [C++]  (0) 2020.12.08
백준 16234[C++]  (0) 2020.10.25
백준 18405 [C++]  (0) 2020.10.25
백준 17471 [C++]  (0) 2020.10.19

0.Transitive Closure

- 그래프 G가 주어졌을 떄 G*은 G와 같은 정점집합(same vertices)을 가진다.

- 만약 그래프 G가 정점 u에서 v로 경로를 가지면 그래프 G*는 정점 u에서 v로 간선(edge)를 가진다.

- Transitive Closure은 경로가 존재하는 지 여부를 알 수 있다.

- 물론 모든 정점에서 DFS를 수행하면 O(n(n+m)) --링크드리스트로 구현되어있다면

  에 알아낼 수 있다.

 

1. 개요

- 플로이드 워셜 알고리즘은 그래프에서 Transitive Closure을 구하거나

  n:n(다대다) shortest path를 구하는 데 사용 된다.

- Dynamic Programming 알고리즘이다.

- "A에서 B로 갈 수 있고 B에서 C로 갈 수 있는데 AC간선이 없다면, 간선을 연결해준다."

 

 

2.아이디어

- 모든 정점들을 번호로 관리한다.

- n단계로 구성되어 차례차례 확장해나가는 구조.

- k번째 단계의 수행이 완료되면, 1~k까지의 간선들은 모두 활용한 것 이다.

- 친구들끼리 연락을 해야하는 상황을 생각해보면 이해가 쉽다.

   (난 A의 전화번호를 모르지만 B의 번호를 알고있다. B는C의 번호를알고있다.

     그럼 난 두 단계를 거치면 C의 번호를 알게된다.)

 

 

3.The Floyd-Warshall Algorithm(플로이드 워셜 알고리즘)

- 각 단계의 그래프를 G0,G1,.......Gn이라 하자.

- 정점들은 v1,v2,.....,vn이라 한다.

- k단계에서 Gk는 Gk-1으로 부터 계산한다.

- 수행시에 adjacent연산을 많이 쓰는데 (두 정점 사이에 경로가 있는지 u->v)

   그럼 Graph를 구현 할 때 인접행렬로 구현하는 게 좋겠죠~

- 전화번호 예시에 빗대어 설명하였습니다.

-그럼 n:n shortes path는 어떻게 구하느냐??
- 기본적인 원리는 위와 같습니다만, 새로 알게된 경로가 기존의 경로보다 짧을 경우에 그 값을 넣어주고

   그렇지 않은 경우는 update하지 않습니다.

- 처음 초기화를 무한대로 해줍니다.

 

 

4.Example

(1)

(2)

(3)

(4)

(5)

 

5. 분석(Analysis)

- n:n shortest path를 구할 때 n번의 다익스트라 알고리즘을 호출하면 O(nmlogn)의 시간 복잡도를 가진다.

- 플로이드 워셜 알고리즘은 O(n*3)의 시간 복잡도를 가진다.

 

0. 시작에 앞서...

- 만약, 그래프가 가중치가 모두 같은 간선들로 이루어져 있다면 BFS(넓이 우선탐색)을 통하여 쉽게

   최단거리를 구할 수 있다.

- 오늘은 가장 유명한 최단거리 구하는 알고리즘인 다익스트라 알고리즘에 대하여 알아보겠다.

 

 

1. Shortest-Path 정의

- 그래프 G=(V,E,W)에서 P는 nonempty-path이라 하자

- W(P) (Weight of P) = the sum of the weights (각 간선들의 가중치의 합)  이다.

- 만약 x=y (즉 같은 정점) 사이의 가중치는 0 이다.

- x정점과 y정점사이에 W(P)보다 가중치가 작은 path가 없다면 이 경로가

    shortest-path or minimum-weight path이다

 

 

2.Properties of Shortest Paths

- Lemma: shortest path property

- 간단하게 말하면 최단경로는 최단경로들로 구성되어있다 라는 것.

- 이는 귀류법으로 손쉽게 증명할 수 있다.

- if) P가 최단경로가 아니거나 Q가 최단경로가 아니라면(즉, 위 그림처럼 P'가 존재)

           W(P')<W(P)이고 W(P')+W(Q)<W(P)+W(Q) 즉 R이 최단경로가 아니다.

 

3. Dijkstra's Algorithm(다익스트라 알고리즘)

- Weight are nonnegative (가중치는 음수가 아니여야한다.)

- greedy 알고리즘 이기도 하며 dynamic programming 알고리즘 이기도 하다.

- 기본적인 구조는 prim 알고리즘과 비슷하다.

 

 

4.Example

- 가중치가 같다면 알파벳 순서로 선택한다고 가정.

(1) A-출발점

(2) 가중치가 가장 짧은 간선 2를 선택 결과 테이블 UPDATE

(3) AG(3)을 선택

(4) BC(4)를 선택

(.....) 이런식으로 테이블을 업데이트 해서 끝나면 A점으로 부터 다른 정점들로의

최단거리를 테이블에서 불러오기만 하면 된다.

 

 

5.Correctness

- 새로운 경로가 나타날 수 도 있는데 최단경로를 이렇게 확정해버려도 되는가?

- 간선의 가중치는 음수가 아니므로 새로운 경로가 나타도 같을 순 있어도, 

   더 짧은 경로가 나타날 순 없다.

 

6.분석(Analysis)

- 힙자료구조를 이용한 우선순위 큐 사용시 시간복잡도는 O(mlogm) = O(mlogn)

이라 할 수 있습니다.

+ Recent posts