SRM471 Div2 Hard(1000) Thirteen

Thirteen

Div1 Mediumとの違いは、経路上の任意の2駅間ではなく最初の駅からの任意の駅までの時間のみが13の倍数にならないこと。
駅の番号と、その駅に到達する時刻を13で割った余りを合わせて1つのノードとした最短経路問題。

#include <string>
#include <vector>
#include <algorithm>

using namespace std;

class Thirteen
{
    int time( char c );
public:
    int calcTime( vector <string> city );
};

int Thirteen::time( char c )
{
    if ( 'A' <= c  &&  c <= 'Z' )  return c - 'A' + 1;
    if ( 'a' <= c  &&  c <= 'z' )  return c - 'a' + 27;
    return -1;
}

int Thirteen::calcTime( vector <string> city )
{
    int N = (int)city.size();

    vector<vector<int> > T( N, vector<int>( 13, INT_MAX ) );
    vector<vector<bool> > F( N, vector<bool>( 13, false ) );
    T[0][0] = 0;
    F[0][0] = true;

    bool update;
    do
    {
        update = false;

        for ( int fc=0; fc<N; fc++ )
        for ( int fr=0; fr<13; fr++ )
        if ( F[fc][fr] )
        {
            for ( int tc=0; tc<N; tc++ )
            {
                int t = time( city[fc][tc] );
                if ( t >= 0 )
                {
                    int tr = ( T[fc][fr] + t ) % 13;

                    if ( tr != 0  &&
                         T[tc][tr] > T[fc][fr] + t )
                    {
                        update = true;
                        T[tc][tr] = T[fc][fr] + t;
                        F[tc][tr] = true;
                    }
                }
            }

            F[fc][fr] = false;
        }
    } while ( update );

    int ans = *min_element( T[N-1].begin(), T[N-1].end() );

    return ans<INT_MAX ? ans : -1;
}