#include <vector>
#include <map>
#include <queue>
#include <iostream>
#include <sstream>
#include <fstream>
using namespace std;
struct Route;
struct Terminal
{
Terminal() : timeArrive( 10000 ), count( 10000 ) {}
int count; // ν΄λΉ μ λμ°©κΉμ§ νμν λ¦¬ν° μ.
int timeArrive; // ν΄λΉ μμ λμ°©ν μκ°.
string strName; // μ μ΄λ¦
vector<Route*> routes; // μμμ μΆλ°νλ λ
Έμ λ°μ΄ν°.
};
struct Route
{
Route() : pStart( NULL ), pEnd( NULL ), timeStart( 0 ), timeDuration( 0 ) {}
Terminal* pStart; // μΆλ°μ
Terminal* pEnd; // λμ°©μ
int timeStart; // μΆλ°μκ°
int timeDuration; // μμμκ°
int GetArriveTime() const { return timeStart + timeDuration; }
};
class Graph
{
public:
Graph( istream& stm ) : m_stmIn( stm ) {}
void Solve();
protected:
void Init();
Terminal* RegistTerminal( const string& strTerminal );
Terminal* GetTerminal( const string& strTerminal );
// search
void Bfs( Terminal* pStart, Terminal* pEnd );
//------------------------------------------------------------------------
map<string,Terminal> m_terminals; // μ λ₯μ₯ 리μ€νΈ
vector<Route*> m_routes; // λ
Έμ 리μ€νΈ
istream& m_stmIn; // νμΌμ
λ ₯ or STDIN μ
λ ₯.
};
void Graph::Init()
{
for( size_t i = 0; i < m_routes.size(); i++ )
{
delete m_routes[i];
m_routes[i] = NULL;
}
m_terminals.clear();
m_routes.resize(0);
}
Terminal* Graph::RegistTerminal( const string& strTerminal )
{
map<string,Terminal>::iterator mit;
mit = m_terminals.find( strTerminal );
if( mit != m_terminals.end() )
return &mit->second;
// insertion.
m_terminals[strTerminal].strName = strTerminal;
return &m_terminals[strTerminal];
}
void Graph::Bfs( Terminal* pStart, Terminal* pEnd )
{
queue<Terminal*> queue;
queue.push( pStart );
pStart->count = 0;
pStart->timeArrive = 0;
while( !queue.empty() )
{
Terminal* pTerminal = queue.front();
queue.pop();
// λͺ©μ μ§μ ν λ² λλ¬νλλΌλ λ€μμΌλ‘ μ§ν. λ μ§§μ κ²½λ‘λ₯Ό μ°Ύμ μ μλ€.
if( pTerminal == pEnd )
{
continue;
}
const vector<Route*>& edges = pTerminal->routes;
vector<Route*>::const_iterator vit;
for( vit = edges.begin(); vit != edges.end(); vit++ )
{
const Route& route = *(*vit);
// λΉμΌμ μ μ μμ§ μκ³ λ€μ μ¬νν μ μλ 쑰건
// 1. μΆλ°μμ λμ°©ν μκ°λ³΄λ€ λ λ€μ μΆλ°νλ μ΄μ°¨μΌ κ².
// 2-1. λμ°©μμ μ΄λ―Έ λ λΉ λ₯Έ κ²½λ‘λ‘ λ°©λ¬Έν μ μ΄ μκ±°λ
// 2-2. λμΌν μμκΈ°κ°μ΄λΌλ λμ°©μκ°μ λ¨μΆν μ μλ κ²½μ°.
if( pTerminal->timeArrive <= route.timeStart &&
( route.pEnd->count > pTerminal->count ||
( route.pEnd->count == pTerminal->count &&
route.pEnd->timeArrive > route.GetArriveTime() ) ) )
{
queue.push( route.pEnd );
route.pEnd->count = pTerminal->count;
route.pEnd->timeArrive = route.GetArriveTime();
}
// νμ¨ μκ³ λ€μλ μ¬ννλ κ²½λ‘μ νμ 쑰건
// 1-1. λμ°©μμ νμ¬ μμμΌμ+1 λ§νΌ μ§§μ λ°©λ¬ΈκΈ°λ‘μ΄ μκ±°λ
// 1-2. νμ¬ μμμΌμ+1μ κΈ°λ‘μ΄ μλλΌλ λμ°©μκ° λ¨μΆμ΄ κ°λ₯ν κ²½μ°.
else if( route.pEnd->count > pTerminal->count + 1 ||
( route.pEnd->count == pTerminal->count + 1 &&
route.pEnd->timeArrive > route.GetArriveTime() ) )
{
queue.push( route.pEnd );
route.pEnd->count = pTerminal->count + 1;
route.pEnd->timeArrive = route.GetArriveTime();
}
}
}
}
Terminal* Graph::GetTerminal( const string& strTerminal )
{
map<string,Terminal>::iterator mit = m_terminals.find( strTerminal );
if( mit == m_terminals.end() )
return NULL;
return &mit->second;
}
void Graph::Solve()
{
int caseCount = 0;
m_stmIn >> caseCount;
m_stmIn.get();
for( int i = 0; i < caseCount; i++ ) // ν
μ€νΈ μΌμ΄μ€ κ°μλ§νΌ 루ν.
{
Init();
int edgeCount = 0;
string inputLine;
m_stmIn >> edgeCount;
m_stmIn.get();
for( int j = 0; j < edgeCount; j++ ) // μ΄μ°¨λ
Έμ κ°μλ§νΌ 루ν.
{
string strStart, strEnd;
int timeStart, timeDuration;
m_stmIn >> strStart >> strEnd >> timeStart >> timeDuration;
m_stmIn.get();
timeStart %= 24;
int timeArrive = timeStart + timeDuration;
if( (6 <= timeStart && timeStart < 18) || // μΆλ°μκ°μ΄ 6:00 ~ 18:00 μ¬μ΄
(timeStart < 6 && timeArrive > 6) || // μλ²½ μΆλ°μΈλ° λμ°©μκ° 06:00 μ΄κ³Ό
(timeStart >= 18 && timeArrive > 30) ) // μ λ
μΆλ°μΈλ° λμ°©μκ° λ€μλ 06:00 μ΄κ³Ό
{
continue;
}
Route* pRoute = new Route;
pRoute->pStart = RegistTerminal( strStart );
pRoute->pEnd = RegistTerminal( strEnd );
pRoute->timeStart = (timeStart + 12) % 24;
pRoute->timeDuration = timeDuration;
pRoute->pStart->routes.push_back( pRoute );
m_routes.push_back( pRoute );
}
string strStart, strEnd;
m_stmIn >> strStart >> strEnd;
m_stmIn.get();
Terminal* pStart = GetTerminal( strStart );
Terminal* pEnd = GetTerminal( strEnd );
cout << "Test Case " << i + 1 << "." << endl;
if( pStart && pEnd )
{
Bfs( pStart, pEnd );
}
if( pEnd && pEnd->timeArrive < 30 )
cout << "Vladimir needs " << pEnd->count << " litre(s) of blood." << endl;
else
cout << "There is no route Vladimir can take." << endl;
}
}
int main( int argc, char* argv[] )
{
if( argc > 1 ) // λͺ
λ Ήν μΈμλ₯Ό λ°λλ€λ©΄ ν΄λΉ μ΄λ¦μ νμΌμ μΈνμΌλ‘ μΌλλ€.
{
ifstream fstm( argv[1] );
Graph g( fstm );
g.Solve();
}
else // κ·Έλ₯ μ€ννλ©΄ νμ€μ
λ ₯μΌλ‘ μΈνμ λ°μ.
{
Graph g( cin );
g.Solve();
}
return 0;
}