새소식

코딩테스트/백준_골드

[C++][백준 11404] 플로이드

  • -

[문제]

11404번: 플로이드 (acmicpc.net)


[문제 풀이]

플로이드-워셜(플로이드 와샬)에 대해서 알아보도록 하자!

 

해당 문제를 예시로 플로이드 와샬을 하는 방법에 대해서 알아보자.

 

문제의 조건에 맞는 행렬을 우선 만들어보자.

  2 3 1(2) 10
      2  
8     1(2) 10(1)
        3
7 4      

 

여기에서 가장 짧은 거리를 알아야 하니까 원소에서 중복되는 값은 짧은 값만 남겨주자.

  2 3 1 10
      2  
8     1 1
        3
7 4      

그러면 이제 i 에서 j 로 한번도 걸치지 않고 바로 가는 그래프에 대해서 알게 되었다. 해당 그래프를 이용해서 n번을 걸쳐서 가는 루트중에 가장 짧은 루트를 알아보자

 

i, j 에서 1을 통해서 걸쳐가는 루트에 대해서 알아보도록 하자.

[i][1] + [1][j]는 곧 i에서 j로 갈 수 있다는 의미이므로 해당 술식을 이용하자.

1을 통해서 가는 경우

  2 3 1 10
      2  
8 10(8+2)   1, 9(8+1) 1, 18(8+10)
        3
7 4, 9(7+2) 10(7+3) 8(7+1)  

 

2를 통해서 가는 경우

  2 3 1 3(2+1) 10 12(2+10)
      2  
8 10   1 12(10 + 2) 1
        3
7 4 10 8 6(4+ 2)  

3을 통해서 가는 경우

  2 13(3+10) 3 1 4(3+1) 10 4(3+1)
      2  
8 10   1 1
        3
7 18(10+8) 4 20(10+10) 10 6 11(10+1)  

4를 통해서 가는 경우

  2 3 1  4 4(1+3)
      5(2+3)
8 10   1 1
        3
7  4 10 6  

5를 통해서 가는 경우

  2 8(4+4) 3 14(4+10) 1 10(4+6) 4
12(5+7)   15(5+15) 2 11(5+6)  5
8 8(1+7) 10 5(1+4)   1 7(1+6) 1
10(3+7) 7(3+4) 13(3+10)   3
7  4 10 6  

 

해당 과정을 통해서 정답을 알 수가 있다.

이제 해당 과정을 코드로 바꿔보자.

*주의 사항 : 중간에 통해서 가는 곳을 가장 바깥쪽에 둬야 한다. 안 그럴 경우 모든 경우를 확인하기가 힘들다.


[코드]

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

const int INF = 100000000;
int city[101][101];

void floid(int n){

    for(int k = 1;k<=n;k++){
        for(int i = 1;i<=n;i++){
            for(int j = 1;j<=n;j++){
                if(city[i][j] > city[i][k] + city[k][j]){
                    city[i][j] = city[i][k] + city[k][j];
                }
            }
        }
    }

    return;
}

int main(){
    int n;
    int m;
    cin>>n>>m;
    
    fill(city[0],city[n + 1],INF);

    for(int i = 0;i<m;i++){
        int a,b,temp;
        cin>>a>>b;
        cin>>temp;
        city[a][b] = min(city[a][b],temp);
    }

    for(int i = 1;i<=n;i++){
        city[i][i] = 0;
    }

    floid(n);

    for(int i = 1;i<=n;i++){
        for(int j = 1;j<=n;j++){
            if(city[i][j] == INF){
                cout<<0<<" ";
                continue;
            }
            cout<<city[i][j]<<" ";
        }
        cout<<endl;
    }

    return 0;
}

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.