본문으로 바로가기

[Floyd] 11404번 플로이드

category Algorithm/BOJ 문제풀이 2018. 12. 9. 21:30
11404_플로이드

11404번 플로이드

 

https://www.acmicpc.net/problem/11404


 

문제

n(1≤n≤100)개의 도시가 있다. 그리고 한 도시에서 출발하여 다른 도시에 도착하는 m(1≤m≤100,000)개의 버스가 있다. 각 버스는 한 번 사용할 때 필요한 비용이 있다.

모든 도시의 쌍 (A, B)에 대해서 도시 A에서 B로 가는데 필요한 비용의 최솟값을 구하는 프로그램을 작성하시오.

 

입력

첫째 줄에 도시의 개수 n(1≤n≤100)이 주어지고 둘째 줄에는 버스의 개수 m(1≤m≤100,000)이 주어진다. 그리고 셋째 줄부터 m+2줄까지 다음과 같은 버스의 정보가 주어진다. 먼저 처음에는 그 버스의 출발 도시의 번호가 주어진다. 버스의 정보는 버스의 시작 도시 a, 도착 도시 b, 한 번 타는데 필요한 비용 c로 이루어져 있다. 시작 도시와 도착 도시가 같은 경우는 없다. 비용은 100,000보다 작거나 같은 자연수이다.

 

출력

N개의 줄을 출력해야 한다. i번째 줄에 출력하는 j번째 숫자는 도시 i에서 j로 가는데 필요한 최소 비용이다. 만약, i에서 j로 갈 수 없는 경우에는 그 자리에 0을 출력한다.

 

예제 입력

5
14
1 2 2
1 3 3
1 4 1
1 5 10
2 4 2
3 4 1
3 5 1
4 5 3
3 5 10
3 1 8
1 4 2
5 1 7
3 4 2
5 2 4

 

예제 출력

0 2 3 1 4
12 0 15 2 5
8 5 0 1 1
10 7 13 0 3
7 4 10 6 0

 

해결방법

모든 노드들간의 최단 경로를 구하는 All-to-All 최단 경로 문제이다

 

플로이드 와샬 알고리즘은 O(n³) 의 시간 복잡도를 가진다

n의 조건이 n≦ 100 으로 충분히 플로이드 와샬 알고리즘을 사용할 수 있다

 

초기에 i==j 일 경우, 최단 경로를 0으로

아닌 경우, 최단 경로를 INF 로 설정해준다

 

그리고 나서 3중 for문으로 플로이드 와샬 알고리즘을 수행한다

// Floyd
for(int k=1; k<=n; k++){
    for(int i=1; i<=n; i++){
        for(int j=1; j<=n; j++){
            if(i==j) continue;
            if(k==i || k==j) continue;
            
            if(dist[i][j] > dist[i][k] + dist[k][j]){
                dist[i][j] = dist[i][k] + dist[k][j];
            }
        }
    }
}

 

 

소스코드

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <bitset>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
#define MAX 101
#define INF 987654321
using namespace std;

typedef pair<int, int> pii;

int n,m;
int u,v,w;

int adj[MAX][MAX];
int dist[MAX][MAX];

void floyd(){
    // K=0 인 경우 초기화
    for(int i=1; i<=n; i++){
        for(int j=1; j<=n; j++){
            if(i==j) continue;
            
            if(adj[i][j] != INF){
                dist[i][j] = adj[i][j];
            }else{
                dist[i][j] = INF;
            }
        }
    }
    
    // Floyd
    for(int k=1; k<=n; k++){
        for(int i=1; i<=n; i++){
            for(int j=1; j<=n; j++){
                if(i==j) continue;
                if(k==i || k==j) continue;
                
                if(dist[i][j] > dist[i][k] + dist[k][j]){
                    dist[i][j] = dist[i][k] + dist[k][j];
                }
            }
        }
    }
    
    // Print
    for(int i=1; i<=n; i++){
        for(int j=1; j<=n; j++){
            if(dist[i][j] == INF) cout << 0 << " ";
            else cout << dist[i][j] << " ";
        }
        cout << "\n";
    }
}

int main(int argc, const char * argv[]) {
    // cin,cout 속도향상
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
    
    cin >> n;
    cin >> m;
    
    for(int i=0; i<MAX; i++){
        for(int j=0; j<MAX; j++){
            if(i==j) adj[i][j] = 0;
            else adj[i][j] = INF;
        }
    }
    
    for(int i=0; i<m; i++){
        cin >> u >> v >> w;
        
        if(adj[u][v] > w) adj[u][v] = w;
    }
    
    floyd();
}

'Algorithm > BOJ 문제풀이' 카테고리의 다른 글

[Floyd] 1613번 역사  (0) 2018.12.09
[Floyd] 10159번 저울  (0) 2018.12.09
[Floyd] 11403번 경로 찾기  (0) 2018.12.09
[BFS] 5567번 결혼식  (0) 2018.12.09
[BFS] 2644번 촌수계산  (0) 2018.12.09