Aizu Online Judge 2200 Mr. Rito Post Office

へーあんたも離島っていうんだー(バカかお前)
陸路のみと海路のみのそれぞれのグラフにワーシャルフロイドかけてから、memo[i][j]:=島jに船を置いた状態でi番目の島を訪れたときの最短距離 でdp(拡張ダイクストラ法も時間があればまた)

#include<cstdio>
#include<algorithm>
using namespace std;
static const int MAX_N = 200;
static const int MAX_R = 1000;
static const int INF = 1 << 20;
 
int N, M;
int x, y, t; char sl;
int R;
int z[MAX_R];
 
int dist1[MAX_N][MAX_N], dist2[MAX_N][MAX_N];
int memo[MAX_R][MAX_N];
 
int main(){
    for(;;){
        scanf("%d %d", &N, &M);
        if(N == 0 && M == 0) break;
        for(int i = 0; i < N; i++){
            for(int j = 0; j < N; j++){
                if(i == j){
                    dist1[i][j] = 0;
                    dist2[i][j] = 0;
                }else{
                    dist1[i][j] = INF;
                    dist2[i][j] = INF;
                }
            }
        }
        for(int i = 0; i < M; i++){
            scanf("%d %d %d %c", &x, &y, &t, &sl);
            x--; y--;
            if(sl == 'L'){
                dist1[x][y] = min(dist1[x][y], t);
                dist1[y][x] = min(dist1[y][x], t);
            }else if(sl == 'S'){
                dist2[x][y] = min(dist2[x][y], t);
                dist2[y][x] = min(dist2[y][x], t);
            }
        }
        for(int k = 0; k < N; k++){
            for(int i = 0; i < N; i++){
                for(int j = 0; j < N; j++){
                    if(dist1[i][j] > dist1[i][k] + dist1[k][j]) dist1[i][j] = dist1[i][k] + dist1[k][j];
                    if(dist2[i][j] > dist2[i][k] + dist2[k][j]) dist2[i][j] = dist2[i][k] + dist2[k][j];
                }
            }
        }
        scanf("%d", &R);
        for(int i = 0; i < R; i++){
            scanf("%d", &z[i]);
            z[i]--;
        }
        fill(memo[0], memo[R], INF);
        for(int i = 0; i < R; i++){
            for(int j = 0; j < N; j++){
                if(i == 0){
                    if(j == z[i]) memo[i][j] = 0;
                }else{
                    memo[i][j] = min(memo[i][j], min(memo[i - 1][j] + dist1[z[i - 1]][z[i]], INF));
                    for(int k = 0; k < N; k++){
                        memo[i][k] = min(memo[i][k], min(memo[i - 1][j] + dist1[z[i - 1]][j] + dist2[j][k] + dist1[k][z[i]], INF));
                    }
                }
            }
        }
        int res = INF;
        for(int i = 0; i < N; i++) res = min(res, memo[R - 1][i]);
        printf("%d\n", res);
    }
    return 0;
}