Problem:
Problem C: Seishun 18 Kippu
R大学のとある学生sirokurostoneはA津大学で行われる合宿に参加しようとしていた。
他のメンバーは新幹線を使用する予定なのだが、sirokurostoneは青春18切符を使って向かおうとしていた。
同じく青春18切符使いのとある2D好きな人物も合宿に参加しようとしていた。
どうせならと一緒に行こうと考えたsirokurostoneは途中の駅で2D好きな彼を拾って向かおうと考えた。
sirokurostoneはR大学を出る前に遅延状況を確認してすこしでも時間のかからないルートを通ってA津大学のある駅に着きたいと考えている。
sirokurostoneはルートが確定した後に2D好きな彼にもその情報を伝えるつもりである。
しかし、sirokurostoneは遅延状況を見てもどのルートを通れば早くA津大学のある駅に到着できるか分からず困っている。
そこで、あなたの仕事はsirokurostoneに代わって遅延状況からどれくらいでA津大学のある駅に着くのかを求めることである。
各駅間には、駅間の距離と遅延予想時間がある。
電車は動き始めてから40km/hを維持するものとする。
地点aと地点bの間の移動時間は、
距離/40+遅延予想時間
で求めることができる。
各駅での停車時間は無視してよいものとする。
Input
複数のデータセットの並びが入力として与えられる。
データセット数は50以下であることが保障されている。
各データセットは、次の形式をしている。
n
m
s
p
g
a
1
b
1
d
1
t
1
...
a
i
b
i
d
i
t
i
...
a
m
b
m
d
m
t
m
整数
n
(
3 ≤ n ≤ 500
)と
m
(
2 ≤ m ≤ 5000
)は、それぞれ駅の数、各駅間の線路の数の合計を表す。
s
、
p
、
g
は、それぞれsirokurostoneが乗る駅、2D好きな人物が乗る駅、A津大学がある駅の場所を示す文字列である。
s
、
p
、
g
はそれぞれ違う文字列である。
続く
m
行は、駅間情報を表す。
a
i
、
b
i
は、線路がつなぐ駅を示す文字列である。
a
i
と
b
i
は、双方向に行き来することができる。
a
i
と
b
i
が一致することはない。
整数
d
i
(
40 ≤ d
i
≤ 10000
)は、
a
i
と
b
i
の距離を表す。
d
i
は40の倍数であることが保証されている。
整数
t
i
(
0 ≤ t
i
≤ 20
)は、
a
i
と
b
i
の間の遅延予想時間を示す。
駅名を表す文字列は、全てアルファベットの小文字および大文字からなる20文字以下の文字列であらわされる。
駅と駅の間の線路は高々1本である。
入力の終わりは2つのゼロを含む行で表される。
Output
入力データセットごとに、A津大学がある駅への到達時間(単位:時間)を出力せよ。
sirokurostoneが乗る駅から2D好きな人が乗る駅までの経路と、2D好きな人物が乗る駅からA津大学がある駅の場所までの経路があることが保証されている。
Sample Input
4 4
A B G
A B 40 3
B C 80 0
A G 40 0
B G 80 0
5 6
Kusatsu Tokyo Aizu
Tokyo Nagoya 120 3
Kusatsu Nagoya 40 0
Kusatsu Kanazawa 40 0
Kanazawa Aizu 40 0
Tokyo Kanazawa 40 0
Tokyo Aizu 80 4 
0 0
Output for Sample Input
5
4

Submitted solutions:

code_snippet: #include <iostream>
#include <vector>
#include <map>
#include <set>

using namespace std;
using ll = long long;

const ll INF = static_cast<ll>(1) << 62;

void solve() {
    ll n, m; cin >> m;
    string s, t, f; cin >> s >> t >> f;
    map<string, vector<pair<string, ll>>>g;
    map<string, ll>d;
    for (int i = 0; i < m; i++) {
        string a, b; cin >> a >> b;
        d[a] = INF;
        d[b] = INF;
        ll d; cin >> d;
        ll t; cin >> t;
        g[a].emplace_back(b, d / 40 + t);
        g[b].emplace_back(a, d / 40 + t);
    }
    set<pair<ll, string>>q;
    q.insert({0, t});
    d[t] = 0;
    while (!q.empty()) {
        ll val = q.begin() -> first;
        string v = q.begin() -> second;
        q.erase(q.begin());
        for (auto [to, w] : g[v]) {
            if (d[v] + w < d[to]) {
                q.erase({d[to], to});
                d[to] = d[v] + w;
                q.insert({d[to], to});
            }
        }
    }
    cout << d[s] + d[f] << '\n';
}

int main() {
    ll T; cin >> T;
    while (T != 0) {
        solve();
        cin >> T;
    }
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 4092
final_rank: 14

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}
inline double time() {
    return static_cast<long double>(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count()) * 1e-9;
}

template<typename T>
struct Dijkstra{
    const T inf=numeric_limits<T>::max();
    using P=pair<T,int>;
    int n;
    vector<vector<pair<int,T>>> g;
    vector<T> d;
    Dijkstra(int n):n(n),g(n),d(n){}
    void add_edge(int u,int v,T w){
        g[u].emplace_back(v,w);
        g[v].emplace_back(u,w);
    }
    vector<T> build(int s){
        for(int i=0;i<n;i++){
            d[i]=inf;
        }
        d[s]=0;
        priority_queue<P,vector<P>,greater<P>> pq;
        pq.emplace(d[s],s);
        while(pq.size()){
            P p=pq.top(); pq.pop();
            int v=p.second;
            if(d[v]<p.first)continue;
            for(auto &e:g[v]){
                int u=e.first; T c=e.second;
                if(d[u]>d[v]+c){
                    d[u]=d[v]+c;
                    pq.emplace(d[u],u);
                }
            }
        }
        return d;
    }
};

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n,m;
    while(cin >> n >> m, n) {
        map<string,int> mp;
        auto id = [&]() -> int {
            string s; cin >> s;
            if (mp.find(s) != mp.end()) {
                return mp[s];
            }
            else {
                int i = mp.size();
                mp[s] = i;
                return i;
            }
        };
        int a = id(), b = id(), c = id();
        Dijkstra<int> g(n);
        for (int i = 0; i < m; ++i) {
            int x = id(), y = id();
            int d,t; cin >> d >> t;
            g.add_edge(x, y, d/40+t);
        }
        cout << g.build(a)[b] + g.build(b)[c] << "\n";
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3392
final_rank: 2

code_snippet: #line 2 "/home/yuruhiya/programming/library/template/template.cpp"
#include <bits/stdc++.h>
#line 4 "/home/yuruhiya/programming/library/template/constants.cpp"
#include <string_view>
#line 7 "/home/yuruhiya/programming/library/template/constants.cpp"

#define rep(i, n) for (int i = 0; i < (n); ++i)
#define FOR(i, m, n) for (int i = (m); i < (n); ++i)
#define rrep(i, n) for (int i = (n)-1; i >= 0; --i)
#define rfor(i, m, n) for (int i = (m); i >= (n); --i)
#define unless(c) if (!(c))
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define range_it(a, l, r) (a).begin() + (l), (a).begin() + (r)

using namespace std;
using ll = long long;
using LD = long double;
using VB = vector<bool>;
using VVB = vector<VB>;
using VI = vector<int>;
using VVI = vector<VI>;
using VL = vector<ll>;
using VVL = vector<VL>;
using VS = vector<string>;
using VD = vector<LD>;
using PII = pair<int, int>;
using VP = vector<PII>;
using PLL = pair<ll, ll>;
using VPL = vector<PLL>;
template <class T> using PQ = priority_queue<T>;
template <class T> using PQS = priority_queue<T, vector<T>, greater<T>>;
constexpr int inf = 1000000000;
constexpr long long inf_ll = 1000000000000000000ll, MOD = 1000000007;
constexpr long double PI = 3.14159265358979323846, EPS = 1e-12;
namespace CharacterClass {
	constexpr string_view
	    digit = "0123456789",
	    xdigit = "0123456789ABCDEFabcdef", lower = "abcdefghijklmnopqrstuvwxyz",
	    upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
	    alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
	    alnum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
	    word = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz",
	    punct = R"(!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~)",
	    graph =
	        R"(!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~)",
	    print =
	        R"( !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~)",
	    blank = " \t", space = " \t\n\r\f\v";
}  // namespace CharacterClass
#line 7 "/home/yuruhiya/programming/library/template/Input.cpp"
using namespace std;

#ifdef _WIN32
#define getchar_unlocked _getchar_nolock
#define putchar_unlocked _putchar_nolock
#define fwrite_unlocked fwrite
#define fflush_unlocked fflush
#endif
class Scanner {
	static int gc() {
		return getchar_unlocked();
	}
	static char next_char() {
		char c;
		read(c);
		return c;
	}
	template <class T> static void read(T& v) {
		cin >> v;
	}
	static void read(char& v) {
		while (isspace(v = gc()))
			;
	}
	static void read(bool& v) {
		v = next_char() != '0';
	}
	static void read(string& v) {
		v.clear();
		for (char c = next_char(); !isspace(c); c = gc()) v += c;
	}
	static void read(int& v) {
		v = 0;
		bool neg = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c); c = gc()) v = v * 10 + (c - '0');
		if (neg) v = -v;
	}
	static void read(long long& v) {
		v = 0;
		bool neg = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c); c = gc()) v = v * 10 + (c - '0');
		if (neg) v = -v;
	}
	static void read(double& v) {
		v = 0;
		double dp = 1;
		bool neg = false, after_dp = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c) || c == '.'; c = gc()) {
			if (c == '.') {
				after_dp = true;
			} else if (after_dp) {
				v += (c - '0') * (dp *= 0.1);
			} else {
				v = v * 10 + (c - '0');
			}
		}
		if (neg) v = -v;
	}
	static void read(long double& v) {
		v = 0;
		long double dp = 1;
		bool neg = false, after_dp = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c) || c == '.'; c = gc()) {
			if (c == '.') {
				after_dp = true;
			} else if (after_dp) {
				v += (c - '0') * (dp *= 0.1);
			} else {
				v = v * 10 + (c - '0');
			}
		}
		if (neg) v = -v;
	}
	template <class T, class U> static void read(pair<T, U>& v) {
		read(v.first);
		read(v.second);
	}
	template <class T> static void read(vector<T>& v) {
		for (auto& e : v) read(e);
	}
	template <size_t N = 0, class T> static void read_tuple_impl(T& v) {
		if constexpr (N < tuple_size_v<T>) {
			read(get<N>(v));
			read_tuple_impl<N + 1>(v);
		}
	}
	template <class... T> static void read(tuple<T...>& v) {
		read_tuple_impl(v);
	}
	struct ReadVectorHelper {
		size_t n;
		ReadVectorHelper(size_t _n) : n(_n) {}
		template <class T> operator vector<T>() {
			vector<T> v(n);
			read(v);
			return v;
		}
	};
	struct Read2DVectorHelper {
		size_t n, m;
		Read2DVectorHelper(const pair<size_t, size_t>& nm) : n(nm.first), m(nm.second) {}
		template <class T> operator vector<vector<T>>() {
			vector<vector<T>> v(n, vector<T>(m));
			read(v);
			return v;
		}
	};

public:
	string read_line() const {
		string v;
		for (char c = gc(); c != '\n' && c != '\0'; c = gc()) v += c;
		return v;
	}
	template <class T> T read() const {
		T v;
		read(v);
		return v;
	}
	template <class T> vector<T> read_vector(size_t n) const {
		vector<T> a(n);
		read(a);
		return a;
	}
	template <class T> operator T() const {
		return read<T>();
	}
	int operator--(int) const {
		return read<int>() - 1;
	}
	ReadVectorHelper operator[](size_t n) const {
		return ReadVectorHelper(n);
	}
	Read2DVectorHelper operator[](const pair<size_t, size_t>& nm) const {
		return Read2DVectorHelper(nm);
	}
	void operator()() const {}
	template <class H, class... T> void operator()(H&& h, T&&... t) const {
		read(h);
		operator()(forward<T>(t)...);
	}

private:
	template <template <class...> class, class...> struct Multiple;
	template <template <class...> class V, class Head, class... Tail>
	struct Multiple<V, Head, Tail...> {
		template <class... Args> using vec = V<vector<Head>, Args...>;
		using type = typename Multiple<vec, Tail...>::type;
	};
	template <template <class...> class V> struct Multiple<V> { using type = V<>; };
	template <class... T> using multiple_t = typename Multiple<tuple, T...>::type;
	template <size_t N = 0, class T> void multiple_impl(T& t) const {
		if constexpr (N < tuple_size_v<T>) {
			auto& vec = get<N>(t);
			using V = typename remove_reference_t<decltype(vec)>::value_type;
			vec.push_back(read<V>());
			multiple_impl<N + 1>(t);
		}
	}

public:
	template <class... T> auto multiple(size_t h) const {
		multiple_t<T...> result;
		while (h--) multiple_impl(result);
		return result;
	}
} in;
#define inputs(T, ...) \
	T __VA_ARGS__;     \
	in(__VA_ARGS__)
#define ini(...) inputs(int, __VA_ARGS__)
#define inl(...) inputs(long long, __VA_ARGS__)
#define ins(...) inputs(string, __VA_ARGS__)
#line 7 "/home/yuruhiya/programming/library/template/Output.cpp"
#include <charconv>
#line 10 "/home/yuruhiya/programming/library/template/Output.cpp"
using namespace std;

struct BoolStr {
	const char *t, *f;
	BoolStr(const char* _t, const char* _f) : t(_t), f(_f) {}
} Yes("Yes", "No"), yes("yes", "no"), YES("YES", "NO"), Int("1", "0");
struct DivStr {
	const char *d, *l;
	DivStr(const char* _d, const char* _l) : d(_d), l(_l) {}
} spc(" ", "\n"), no_spc("", "\n"), end_line("\n", "\n"), comma(",", "\n"),
    no_endl(" ", "");
class Output {
	BoolStr B{Yes};
	DivStr D{spc};

public:
	void put(int v) const {
		char buf[12]{};
		if (auto [ptr, e] = to_chars(begin(buf), end(buf), v); e == errc{}) {
			fwrite(buf, sizeof(char), ptr - buf, stdout);
		} else {
			assert(false);
		}
	}
	void put(long long v) const {
		char buf[21]{};
		if (auto [ptr, e] = to_chars(begin(buf), end(buf), v); e == errc{}) {
			fwrite(buf, sizeof(char), ptr - buf, stdout);
		} else {
			assert(false);
		}
	}
	void put(bool v) const {
		put(v ? B.t : B.f);
	}
	void put(vector<bool>::reference v) const {
		put(v ? B.t : B.f);
	}
	void put(char v) const {
		putchar_unlocked(v);
	}
	void put(const char* v) const {
		fwrite_unlocked(v, 1, strlen(v), stdout);
	}
	void put(double v) const {
		printf("%.20f", v);
	}
	void put(long double v) const {
		printf("%.20Lf", v);
	}
	template <class T> void put(const T& v) const {
		cout << v;
	}
	template <class T, class U> void put(const pair<T, U>& v) const {
		put(v.first);
		put(D.d);
		put(v.second);
	}
	template <class InputIterater>
	void put_range(const InputIterater& begin, const InputIterater& end) const {
		for (InputIterater i = begin; i != end; ++i) {
			if (i != begin) put(D.d);
			put(*i);
		}
	}
	template <class T> void put(const vector<T>& v) const {
		put_range(v.begin(), v.end());
	}
	template <class T, size_t N> void put(const array<T, N>& v) const {
		put_range(v.begin(), v.end());
	}
	template <class T> void put(const vector<vector<T>>& v) const {
		for (size_t i = 0; i < v.size(); ++i) {
			if (i) put(D.l);
			put(v[i]);
		}
	}

	Output() = default;
	Output(const BoolStr& _boolstr, const DivStr& _divstr) : B(_boolstr), D(_divstr) {}
	Output& operator()() {
		put(D.l);
		return *this;
	}
	template <class H> Output& operator()(H&& h) {
		put(h);
		put(D.l);
		return *this;
	}
	template <class H, class... T> Output& operator()(H&& h, T&&... t) {
		put(h);
		put(D.d);
		return operator()(forward<T>(t)...);
	}
	template <class InputIterator>
	Output& range(const InputIterator& begin, const InputIterator& end) {
		put_range(begin, end);
		put(D.l);
		return *this;
	}
	template <class T> Output& range(const T& a) {
		range(a.begin(), a.end());
		return *this;
	}
	template <class... T> void exit(T&&... t) {
		operator()(forward<T>(t)...);
		std::exit(EXIT_SUCCESS);
	}
	Output& flush() {
		fflush_unlocked(stdout);
		return *this;
	}
	Output& set(const BoolStr& b) {
		B = b;
		return *this;
	}
	Output& set(const DivStr& d) {
		D = d;
		return *this;
	}
	Output& set(const char* t, const char* f) {
		B = BoolStr(t, f);
		return *this;
	}
} out;
#line 3 "/home/yuruhiya/programming/library/template/Step.cpp"
using namespace std;

template <class T> struct Step {
	using value_type = T;

	class iterator {
		value_type a, b, c;

	public:
		constexpr iterator() : a(value_type()), b(value_type()), c(value_type()) {}
		constexpr iterator(value_type _b, value_type _c, value_type _s)
		    : a(_b), b(_c), c(_s) {}
		constexpr iterator& operator++() {
			--b;
			a += c;
			return *this;
		}
		constexpr iterator operator++(int) {
			iterator tmp = *this;
			--b;
			a += c;
			return tmp;
		}
		constexpr const value_type& operator*() const {
			return a;
		}
		constexpr const value_type* operator->() const {
			return &a;
		}
		constexpr bool operator==(const iterator& i) const {
			return b == i.b;
		}
		constexpr bool operator!=(const iterator& i) const {
			return !(b == i.b);
		}
		constexpr value_type start() const {
			return a;
		}
		constexpr value_type size() const {
			return b;
		}
		constexpr value_type step() const {
			return c;
		}
	};
	constexpr Step(value_type b, value_type c, value_type s) : be(b, c, s) {}
	constexpr iterator begin() const {
		return be;
	}
	constexpr iterator end() const {
		return en;
	}
	constexpr value_type start() const {
		return be.start();
	}
	constexpr value_type size() const {
		return be.size();
	}
	constexpr value_type step() const {
		return be.step();
	}
	constexpr value_type sum() const {
		return start() * size() + step() * (size() * (size() - 1) / 2);
	}
	operator vector<value_type>() const {
		return to_a();
	}
	auto to_a() const {
		vector<value_type> result;
		result.reserve(size());
		for (auto i : *this) {
			result.push_back(i);
		}
		return result;
	}

private:
	iterator be, en;
};
template <class T> constexpr auto step(T a) {
	return Step<T>(0, a, 1);
}
template <class T> constexpr auto step(T a, T b) {
	return Step<T>(a, b - a, 1);
}
template <class T> constexpr auto step(T a, T b, T c) {
	return Step<T>(a, a < b ? (b - a - 1) / c + 1 : 0, c);
}
#line 8 "/home/yuruhiya/programming/library/template/Ruby.cpp"
using namespace std;

template <class F> struct Callable {
	F func;
	Callable(const F& f) : func(f) {}
};
template <class T, class F> auto operator|(const T& v, const Callable<F>& c) {
	return c.func(v);
}

struct Sort_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(begin(v), end(v), f);
			return v;
		});
	}
	template <class T> friend auto operator|(T v, [[maybe_unused]] const Sort_impl& c) {
		sort(begin(v), end(v));
		return v;
	}
} Sort;
struct SortBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(begin(v), end(v),
			     [&](const auto& i, const auto& j) { return f(i) < f(j); });
			return v;
		});
	}
} SortBy;
struct RSort_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(rbegin(v), rend(v), f);
			return v;
		});
	}
	template <class T> friend auto operator|(T v, [[maybe_unused]] const RSort_impl& c) {
		sort(rbegin(v), rend(v));
		return v;
	}
} RSort;
struct RSortBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(begin(v), end(v),
			     [&](const auto& i, const auto& j) { return f(i) > f(j); });
			return v;
		});
	}
} RSortBy;
struct Reverse_impl {
	template <class T> friend auto operator|(T v, const Reverse_impl& c) {
		reverse(begin(v), end(v));
		return v;
	}
} Reverse;
struct Unique_impl {
	template <class T> friend auto operator|(T v, const Unique_impl& c) {
		v.erase(unique(begin(v), end(v), end(v)));
		return v;
	}
} Unique;
struct Uniq_impl {
	template <class T> friend auto operator|(T v, const Uniq_impl& c) {
		sort(begin(v), end(v));
		v.erase(unique(begin(v), end(v)), end(v));
		return v;
	}
} Uniq;
struct Rotate_impl {
	auto operator()(int&& left) {
		return Callable([&](auto v) {
			int s = static_cast<int>(size(v));
			assert(-s <= left && left <= s);
			if (0 <= left) {
				rotate(begin(v), begin(v) + left, end(v));
			} else {
				rotate(begin(v), end(v) + left, end(v));
			}
			return v;
		});
	}
} Rotate;
struct Max_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) { return *max_element(begin(v), end(v), f); });
	}
	template <class T> friend auto operator|(T v, const Max_impl& c) {
		return *max_element(begin(v), end(v));
	}
} Max;
struct Min_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) { return *min_element(begin(v), end(v), f); });
	}
	template <class T> friend auto operator|(T v, const Min_impl& c) {
		return *min_element(begin(v), end(v));
	}
} Min;
struct MaxPos_impl {
	template <class T> friend auto operator|(T v, const MaxPos_impl& c) {
		return max_element(begin(v), end(v)) - begin(v);
	}
} MaxPos;
struct MinPos_impl {
	template <class T> friend auto operator|(T v, const MinPos_impl& c) {
		return min_element(begin(v), end(v)) - begin(v);
	}
} MinPos;
struct MaxBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto max_it = begin(v);
			auto max_val = f(*max_it);
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); max_val < val) {
					max_it = it;
					max_val = val;
				}
			}
			return *max_it;
		});
	}
} MaxBy;
struct MinBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto min_it = begin(v);
			auto min_val = f(*min_it);
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); min_val > val) {
					min_it = it;
					min_val = val;
				}
			}
			return *min_it;
		});
	}
} MinBy;
struct MaxOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto max_val = f(*begin(v));
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); max_val < val) {
					max_val = val;
				}
			}
			return max_val;
		});
	}
} MaxOf;
struct MinOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto min_val = f(*begin(v));
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); min_val > val) {
					min_val = val;
				}
			}
			return min_val;
		});
	}
} MinOf;
struct Count_impl {
	template <class V> auto operator()(const V& val) {
		return Callable([&](auto v) { return count(begin(v), end(v), val); });
	}
} Count;
struct CountIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) { return count_if(begin(v), end(v), f); });
	}
} CountIf;
struct Index_impl {
	template <class V> auto operator()(const V& val) {
		return Callable([&](auto v) -> optional<int> {
			auto result = find(begin(v), end(v), val);
			return result != end(v) ? optional(result - begin(v)) : nullopt;
		});
	}
} Index;
struct IndexIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) -> optional<int> {
			auto result = find_if(begin(v), end(v), f);
			return result != end(v) ? optional(result - begin(v)) : nullopt;
		});
	}
} IndexIf;
struct FindIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) -> optional<typename decltype(v)::value_type> {
			auto result = find_if(begin(v), end(v), f);
			return result != end(v) ? optional(*result) : nullopt;
		});
	}
} FindIf;
struct Sum_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			return accumulate(next(begin(v)), end(v), f(*begin(v)),
			                  [&](const auto& a, const auto& b) { return a + f(b); });
		});
	}
	template <class T> friend auto operator|(T v, const Sum_impl& c) {
		return accumulate(begin(v), end(v), typename T::value_type{});
	}
} Sum;
struct Includes {
	template <class V> auto operator()(const V& val) {
		return Callable([&](auto v) { return find(begin(v), end(v), val) != end(v); });
	}
} Includes;
struct IncludesIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) { return find_if(begin(v), end(v), f) != end(v); });
	}
} IncludesIf;
struct RemoveIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) {
			v.erase(remove_if(begin(v), end(v), f), end(v));
			return v;
		});
	}
} RemoveIf;
struct Each_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				f(i);
			}
		});
	}
} Each;
struct Select_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			using value_type = typename decltype(v)::value_type;
			vector<value_type> result;
			for (const auto& i : v) {
				if (f(i)) result.push_back(i);
			}
			return result;
		});
	}
} Select;
struct Map_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			using result_type = invoke_result_t<F, typename decltype(v)::value_type>;
			vector<result_type> result;
			result.reserve(size(v));
			for (const auto& i : v) {
				result.push_back(f(i));
			}
			return result;
		});
	}
} Map;
struct Indexed_impl {
	template <class T> friend auto operator|(const T& v, Indexed_impl& c) {
		using value_type = typename T::value_type;
		vector<pair<value_type, int>> result;
		result.reserve(size(v));
		int index = 0;
		for (const auto& i : v) {
			result.emplace_back(i, index++);
		}
		return result;
	}
} Indexed;
struct AllOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				if (!f(i)) return false;
			}
			return true;
		});
	}
} AllOf;
struct AnyOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				if (f(i)) return true;
			}
			return false;
		});
	}
} AnyOf;
struct NoneOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				if (f(i)) return false;
			}
			return true;
		});
	}
} NoneOf;

struct Tally_impl {
	template <class F> auto operator()(size_t max_val) {
		return Callable([&](auto v) {
			vector<size_t> result(max_val);
			for (const auto& i : v) {
				result[static_cast<size_t>(i)]++;
			}
			return result;
		});
	}
	template <class T, class value_type = typename T::value_type>
	friend auto operator|(const T& v, Tally_impl& c) {
		map<value_type, size_t> result;
		for (const auto& i : v) {
			result[i]++;
		}
		return result;
	}
} Tally;

template <class T> auto operator*(const vector<T>& a, size_t n) {
	T result;
	for (size_t i = 0; i < n; ++i) {
		result.insert(result.end(), a.begin(), a.end());
	}
	return result;
}
auto operator*(string a, size_t n) {
	string result;
	for (size_t i = 0; i < n; ++i) {
		result += a;
	}
	return result;
}
template <class T, class U> auto& operator<<(vector<T>& a, const U& b) {
	a.insert(a.end(), all(b));
	return a;
}
template <class T> auto& operator<<(string& a, const T& b) {
	a.insert(a.end(), all(b));
	return a;
}
template <class T, class U> auto operator+(vector<T> a, const U& b) {
	a << b;
	return a;
}
template <class T> auto operator+(string a, const T& b) {
	a << b;
	return a;
}
#line 6 "/home/yuruhiya/programming/library/template/functions.cpp"
using namespace std;

template <class T> int sz(const T& v) {
	return v.size();
}
template <class T, class U> int lower_index(const T& a, const U& v) {
	return lower_bound(all(a), v) - a.begin();
}
template <class T, class U> int upper_index(const T& a, const U& v) {
	return upper_bound(all(a), v) - a.begin();
}
template <class T> auto Slice(const T& v, size_t i, size_t len) {
	return i < v.size() ? T(v.begin() + i, v.begin() + min(i + len, v.size())) : T();
}
template <class T> T div_ceil(T n, T m) {
	return (n + m - 1) / m;
}
template <class T> T div_ceil2(T n, T m) {
	return div_ceil(n, m) * m;
}
template <class T> T triangle(T n) {
	return (n & 1) ? (n + 1) / 2 * n : n / 2 * (n + 1);
}
template <class T> T nC2(T n) {
	return (n & 1) ? (n - 1) / 2 * n : n / 2 * (n - 1);
}
template <class T> T middle(const T& l, const T& r) {
	return l + (r - l) / 2;
}
template <class T> bool chmax(T& a, const T& b) {
	if (a < b) {
		a = b;
		return true;
	}
	return false;
}
template <class T> bool chmin(T& a, const T& b) {
	if (a > b) {
		a = b;
		return true;
	}
	return false;
}
template <class T> bool in_range(const T& v, const T& min, const T& max) {
	return min <= v && v < max;
}
template <class T> bool in_square(T n) {
	T s = sqrt(n);
	return s * s == n || (s + 1) * (s + 1) == n;
}
template <class T = long long> T BIT(int b) {
	return T(1) << b;
}
template <class T, class U = typename T::value_type> U Gcdv(const T& v) {
	return accumulate(next(v.begin()), v.end(), U(*v.begin()), gcd<U, U>);
}
template <class T, class U = typename T::value_type> U Lcmv(const T& v) {
	return accumulate(next(v.begin()), v.end(), U(*v.begin()), lcm<U, U>);
}
template <class T, class U> T Pow(T a, U n) {
	T result = 1;
	while (n > 0) {
		if (n & 1) {
			result *= a;
			n--;
		} else {
			a *= a;
			n >>= 1;
		}
	}
	return result;
}
template <class T, class U> T Powmod(T a, U n, T mod) {
	T result = 1;
	while (n > 0) {
		if (n & 1) {
			result = result * a % mod;
			n--;
		} else {
			a = a * a % mod;
			n >>= 1;
		}
	}
	return result;
}
namespace internal {
	template <class T, size_t N> auto make_vector(vector<int>& sizes, const T& init) {
		if constexpr (N == 1) {
			return vector(sizes[0], init);
		} else {
			int size = sizes[N - 1];
			sizes.pop_back();
			return vector(size, make_vector<T, N - 1>(sizes, init));
		}
	}
}  // namespace internal
template <class T, size_t N>
auto make_vector(const int (&sizes)[N], const T& init = T()) {
	vector s(rbegin(sizes), rend(sizes));
	return internal::make_vector<T, N>(s, init);
}
#line 9 "/home/yuruhiya/programming/library/template/template.cpp"
#if __has_include(<library/dump.hpp>)
#include <library/dump.hpp>
#define LOCAL
#else
#define dump(...) ((void)0)
#endif

template <class T> constexpr T oj_local(const T& oj, const T& local) {
#ifndef LOCAL
	return oj;
#else
	return local;
#endif
}
#line 5 "/home/yuruhiya/programming/library/Graph/GraphTemplate.cpp"
using namespace std;

using Weight = long long;
constexpr Weight INF = numeric_limits<Weight>::max();
struct Edge {
	int to;
	Weight cost;
	Edge() : to(-1), cost(-1) {}
	Edge(int _to, Weight _cost = 1) : to(_to), cost(_cost) {}
	friend bool operator<(const Edge& e1, const Edge& e2) {
		return e1.cost < e2.cost;
	}
	friend bool operator>(const Edge& e1, const Edge& e2) {
		return e1.cost > e2.cost;
	}
	friend ostream& operator<<(ostream& os, const Edge& e) {
		return os << "->" << e.to << '(' << e.cost << ')';
	}
};
using Graph = vector<vector<Edge>>;
struct Edge2 {
	int from, to;
	Weight cost;
	Edge2() : from(-1), to(-1), cost(0) {}
	Edge2(int _from, int _to, Weight _cost) : from(_from), to(_to), cost(_cost) {}
	friend bool operator<(const Edge2& e1, const Edge2& e2) {
		return e1.cost < e2.cost;
	}
	friend bool operator>(const Edge2& e1, const Edge2& e2) {
		return e1.cost > e2.cost;
	}
	friend ostream& operator<<(ostream& os, const Edge2& e) {
		return os << e.from << "->" << e.to << '(' << e.cost << ')';
	}
};
using Edges = vector<Edge2>;
using Matrix = vector<vector<Weight>>;
#line 5 "/home/yuruhiya/programming/library/Graph/DijkstraST.cpp"
using namespace std;

Weight Dijkstra(const Graph& graph, int s, int t) {
	int V = graph.size();
	vector<Weight> dist(V, INF);
	dist[s] = 0;
	priority_queue<Edge, vector<Edge>, greater<Edge>> pq;
	pq.emplace(s, 0);
	while (!pq.empty()) {
		Edge p = pq.top();
		pq.pop();
		int v = p.to;
		if (v == t) return dist[t];
		if (dist[v] < p.cost) continue;
		for (auto e : graph[v]) {
			if (dist[e.to] > dist[v] + e.cost) {
				dist[e.to] = dist[v] + e.cost;
				pq.emplace(e.to, dist[e.to]);
			}
		}
	}
	return dist[t];
}
#line 3 "a.cpp"

ll solve(int n, int m) {
	map<string, int> str;
	int k = 0;
	VS s = in[3];
	vector<tuple<string, string, ll>> edges;
	rep(i, m) {
		ins(s, t);
		inl(a, b);
		edges.emplace_back(s, t, a / 40 + b);
		if (str.count(s) == 0) str[s] = k++;
		if (str.count(t) == 0) str[t] = k++;
	}

	Graph g(n);
	for (auto [s, t, d] : edges) {
		g[str[s]].emplace_back(str[t], d);
		g[str[t]].emplace_back(str[s], d);
	}

	int start = str[s[0]], passing = str[s[1]], goal = str[s[2]];
	return Dijkstra(g, start, passing) + Dijkstra(g, passing, goal);
}

int main() {
	while (true) {
		ini(n, m);
		if (n + m == 0) break;
		out(solve(n, m));
	}
}
accuracy: 1
time_ms: 10
memory_kb: 4080
final_rank: 11

code_snippet: #include<iostream>
#include<vector>
#include<set>
#include<map>
#include<queue>
using namespace std;

int main(){
    int n, m;
    while(cin >> n >> m, n+m){
        string s, t, g;
        cin >> s >> t >> g;
        map<string, vector<pair<string,int>>> ma;
        for(int i = 0; i < m; i++){
            string a, b;
            int c, d;
            cin >> a >> b >> c >> d;
            ma[a].push_back({b, c/40+d});
            ma[b].push_back({a, c/40+d});
        }
        map<string,int> dp;
        for(auto p : ma) dp[p.first] = 1<<30;
        dp[s] = 0;
        priority_queue<pair<int,string>> pq;
        pq.push({-0, s});
        while(!pq.empty()){
            auto p = pq.top();  pq.pop();
            string pos = p.second;
            int cost = -p.first;
            if(dp[pos] != cost) continue;
            for(auto next : ma[pos]){
                int ncost = cost + next.second;
                string npos = next.first;
                if(dp[npos] > ncost){
                    dp[npos] = ncost;
                    pq.push({-ncost, npos});
                }
            }
        }
        int ans = dp[t];
        for(auto p : ma) dp[p.first] = 1<<30;
        dp[t] = 0;
        pq.push({-0, t});
        while(!pq.empty()){
            auto p = pq.top();  pq.pop();
            string pos = p.second;
            int cost = -p.first;
            if(dp[pos] != cost) continue;
            for(auto next : ma[pos]){
                int ncost = cost + next.second;
                string npos = next.first;
                if(dp[npos] > ncost){
                    dp[npos] = ncost;
                    pq.push({-ncost, npos});
                }
            }
        }
        ans += dp[g];
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 3836
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

struct edge{ int to,cost; };
const int INF = INT_MAX/3;

int main(){
    int n,m;
    while(cin >>n >>m,n){
        string s,p,g;
        cin >>s >>p >>g;

        map<string,int> name2idx;
        name2idx[s] = 0;
        name2idx[p] = 1;
        name2idx[g] = 2;

        int V = 3;

        vector<string> a(m),b(m);
        vector<int> c(m);
        rep(i,m){
            int d,t;
            cin >>a[i] >>b[i] >>d >>t;

            c[i] = d/40 + t;

            if(!name2idx.count(a[i])){
                name2idx[a[i]] = V;
                ++V;
            }
            if(!name2idx.count(b[i])){
                name2idx[b[i]] = V;
                ++V;
            }
        }

        vector<vector<edge>> G(V);
        rep(i,m){
            int u = name2idx[a[i]], v = name2idx[b[i]];
            G[u].pb({v,c[i]});
            G[v].pb({u,c[i]});
        }

        vector<int> d(V,INF);
        d[1] = 0;

        using pi = pair<int,int>;
        priority_queue<pi, vector<pi>, greater<pi>> pq;
        pq.push({0,1});
        while(!pq.empty()){
            pi now = pq.top();
            pq.pop();
            int v = now.se;
            if(now.fi > d[v]) continue;
            for(const auto &e:G[v]){
                if(d[e.to] > d[v]+e.cost){
                    d[e.to] = d[v]+e.cost;
                    pq.push({d[e.to], e.to});
                }
            }
        }

        cout << d[0]+d[2] << "\n";
    }
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3844
final_rank: 10

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
const ld eps = 1e-9;



int main() {
	while (true) {
		int N,M;cin>>N>>M;
		if(!N)break;
		map<string,int>stmp;
		string S,P,G;cin>>S>>P>>G;
		stmp[S]=0;
		stmp[P]=1;
		stmp[G]=2;
		int id=3;
		vector<vector<pair<int,int>>>edges(N);
		for (int i = 0; i < M; ++i) {
			string s,t;cin>>s>>t;
			int d,c;cin>>d>>c;
			int cost=d/40+c;
			if (stmp.find(s) == stmp.end()) {
				stmp[s]=id++;
			}
			if (stmp.find(t) == stmp.end()) {
				stmp[t]=id++;
			}
			edges[stmp[s]].push_back(make_pair(stmp[t],cost));
			edges[stmp[t]].push_back(make_pair(stmp[s],cost));
		}
		vector<int>memo(N,1e9);
		memo[stmp[P]]=0;
		priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>>que;
		que.push(make_pair(0,stmp[P]));
		while (!que.empty()) {
			auto atop(que.top());
			que.pop();
			int now=atop.second;
			int cost=atop.first;
			for (auto e : edges[now]) {
				const int nextcost=cost+e.second;
				const int next=e.first;
				if (memo[next] > nextcost) {
					memo[next]=nextcost;
					que.push(make_pair(memo[next],next));
				}
			}
		}
		int ans=memo[stmp[S]]+memo[stmp[G]];
		cout<<ans<<endl;

	}
	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3340
final_rank: 4

code_snippet: #include<bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
using namespace std;
string s1,s2,s3,s4,s5;
int ti,dist,n,m,st,go,mi,p1,p2;
int d[502][502];
map<string,int>M;
int main(){
  while(cin>>n>>m,n){
    M.clear();
    r(i,502)r(j,502)d[i][j]=1e8;
    int c=0;
    cin>>s1>>s2>>s3;
    r(i,m){
      cin>>s4>>s5>>dist>>ti;
      if(M[s4])p1=M[s4];
      else M[s4]=++c,p1=M[s4];
      if(M[s5])p2=M[s5];
      else M[s5]=++c,p2=M[s5];
      if(s1==s5)st=M[s5];
      if(s1==s4)st=M[s4];
      if(s2==s5)mi=M[s5];
      if(s2==s4)mi=M[s4];
      if(s3==s5)go=M[s5];
      if(s3==s4)go=M[s4];
      d[p1][p2]=d[p2][p1]=dist/40+ti;
    }
    r(o,n+1)r(i,n+1)r(j,n+1)d[i][j]=min(d[i][j],d[i][o]+d[o][j]);
    cout<<d[st][mi]+d[mi][go]<<endl;
  }
}
accuracy: 1
time_ms: 340
memory_kb: 4216
final_rank: 19

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


struct Info{
	Info(int arg_to,int arg_dist,int arg_delay){
		to = arg_to;
		dist = arg_dist;
		delay = arg_delay;
	}
	int to,dist,delay;
};

struct Data{
	Data(int arg_station,int arg_sum_time){
		station = arg_station;
		sum_time = arg_sum_time;
	}
	bool operator<(const struct Data &arg) const{
		return sum_time > arg.sum_time;
	};
	int station,sum_time;
};

int N,M,index;
char table[500][21];

char start[21],mid[21],goal[21];

bool strCmp(char* base, char* comp){
	int length1,length2;
	for(length1=0;base[length1] != '\0';length1++);
	for(length2=0;comp[length2] != '\0';length2++);
	if(length1 != length2)return false;

	for(int i=0;base[i] != '\0'; i++){
		if(base[i] != comp[i])return false;
	}
	return true;
}

void strcpy(char* to,char* str){
	for(int i=0;str[i] != '\0';i++){
		to[i] = str[i];
		to[i+1] = '\0';
	}
}

void func(){
	scanf("%s %s %s",start,mid,goal);

	strcpy(table[0],start);
	strcpy(table[1],mid);
	strcpy(table[2],goal);

	vector<Info> V[N+1];

	index = 3;

	char left[21],right[21];
	int left_index,right_index,dist,delay;

	bool FLG;

	for(int loop = 0; loop < M; loop++){
		scanf("%s %s %d %d",left,right,&dist,&delay);

		FLG = false;
		for(int i = 0; i < index; i++){
			if(strCmp(table[i],left)){
				left_index = i;
				FLG = true;
				break;
			}
		}
		if(!FLG){
			left_index = index;
			strcpy(table[index++],left);
		}

		FLG = false;
		for(int i = 0; i < index; i++){
			if(strCmp(table[i],right)){
				right_index = i;
				FLG = true;
				break;
			}
		}
		if(!FLG){
			right_index = index;
			strcpy(table[index++],right);
		}

		V[left_index].push_back(Info(right_index,dist,delay));
		V[right_index].push_back(Info(left_index,dist,delay));
	}

	int min_time[N];
	int ans = 0;

	priority_queue<Data> Q;

	for(int loop = 0; loop < 2; loop++){
		for(int i = 0; i < N; i++)min_time[i] = BIG_NUM;
		if(loop == 0){
			min_time[0] = 0;
			Q.push(Data(0,0));
		}else{
			min_time[1] = 0;
			Q.push(Data(1,0));
		}

		while(!Q.empty()){

			if((loop == 0 && Q.top().station == 1) || (loop == 0 && Q.top().station == 1)){
				Q.pop();
			}else if(Q.top().sum_time > min_time[Q.top().station]){
				Q.pop();
			}else{
				for(int i = 0; i < V[Q.top().station].size(); i++){
					if(min_time[V[Q.top().station][i].to] > Q.top().sum_time+V[Q.top().station][i].dist/40+V[Q.top().station][i].delay){
						min_time[V[Q.top().station][i].to] = Q.top().sum_time+V[Q.top().station][i].dist/40+V[Q.top().station][i].delay;
						Q.push(Data(V[Q.top().station][i].to,min_time[V[Q.top().station][i].to]));
					}
				}
				Q.pop();
			}
		}

		if(loop == 0){
			ans += min_time[1];
		}else{
			ans += min_time[2];
		}
	}

	printf("%d\n",ans);
}

int main(){

	while(true){
		scanf("%d %d",&N,&M);
		if(N == 0 && M == 0)break;

		func();
	}
	return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 3328
final_rank: 9

code_snippet: #include <queue>
#include <limits>
#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
struct edge {
	int to, cost;
	edge(int to_, int cost_) : to(to_), cost(cost_) {};
};
bool operator<(const edge& e1, const edge& e2) {
	return e1.cost < e2.cost;
}
template<class Type>
std::vector<Type> shortest_path(std::vector<std::vector<edge> > &G, int s) {
	std::priority_queue<edge> que; que.push(edge(s, 0));
	std::vector<Type> ret(G.size(), std::numeric_limits<Type>::max()); ret[s] = 0;
	while (!que.empty()) {
		edge u = que.top(); que.pop();
		for (edge e : G[u.to]) {
			if (ret[e.to] > ret[u.to] + e.cost) {
				ret[e.to] = ret[u.to] + e.cost;
				que.push(edge(e.to, -ret[e.to]));
			}
		}
	}
	return ret;
}
int n, m, d, e;
int main() {
	while (cin >> n >> m, n) {
		string s, t, g;
		cin >> s >> t >> g;
		vector<string> a(m), b(m), r; vector<int> x(m);
		for (int i = 0; i < m; i++) {
			cin >> a[i] >> b[i] >> d >> e;
			x[i] = d / 40 + e;
			r.push_back(a[i]);
			r.push_back(b[i]);
		}
		sort(r.begin(), r.end());
		r.erase(unique(r.begin(), r.end()), r.end());
		int sp = lower_bound(r.begin(), r.end(), s) - r.begin();
		int tp = lower_bound(r.begin(), r.end(), t) - r.begin();
		int gp = lower_bound(r.begin(), r.end(), g) - r.begin();
		vector<vector<edge> > G(n);
		for (int i = 0; i < m; i++) {
			int ptr1 = lower_bound(r.begin(), r.end(), a[i]) - r.begin();
			int ptr2 = lower_bound(r.begin(), r.end(), b[i]) - r.begin();
			G[ptr1].push_back(edge(ptr2, x[i]));
			G[ptr2].push_back(edge(ptr1, x[i]));
		}
		int w1 = shortest_path<int>(G, sp)[tp];
		int w2 = shortest_path<int>(G, tp)[gp];
		cout << w1 + w2 << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3924
final_rank: 13

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define int long long
#define F first
#define S second
#define all(v) (v).begin(), (v).end()
#define rep(i, n) for(int i = 0; i < (int)(n); i++)
#define reps(i, f, n) for(int i = (int)(f); i < (int)(n); i++)
#define each(a, b) for(auto& a : b)

typedef pair<int, int> P;

const int inf = 1LL << 55;

int G[505][505];

signed main()
{
  int n, m;
  while(cin >> n >> m, n || m) {
    fill(G[0], G[505], inf);
    int cnt = 0;
    map<string, int> stat;
    string s, p, g; cin >> s >> p >> g;
    stat[s] = cnt++; stat[p] = cnt++; stat[g] = cnt++;
    while(m--) {
      string a, b; int d, t;
      cin >> a >> b >> d >> t;
      if(stat.find(a) == stat.end()) stat[a] = cnt++;
      if(stat.find(b) == stat.end()) stat[b] = cnt++;
      G[stat[a]][stat[b]] = G[stat[b]][stat[a]] = d / 40 + t;
    }
    for(int i = 0; i < n; i++) {
      for(int j = 0; j < n; j++) {
	for(int k = 0; k < n; k++) G[j][k] = min(G[j][k], G[j][i] + G[i][k]);
      }
    }
    cout << G[stat[s]][stat[p]] + G[stat[p]][stat[g]] << endl;
  }
  
  return 0;
}
accuracy: 1
time_ms: 370
memory_kb: 5072
final_rank: 20

code_snippet: #include<bits/stdc++.h>
#define rep(i,n)for(int i=0;i<n;i++)
using namespace std;
typedef pair<int, int>P;

int d1[550], d2[550];
char s[50], p[50], g[50], a[50], b[50];
int main() {
	int n, m;
	while (scanf("%d%d", &n, &m), n) {
		unordered_map<string, int>mp;
		vector<P>E[550];
		scanf("%s%s%s", s, p, g);
		mp[s] = 0; mp[p] = 1; mp[g] = 2;
		rep(i, m) {
			int d, t; scanf("%s%s%d%d", a, b, &d, &t);
			if (mp.find(a) == mp.end())mp[a] = mp.size();
			if (mp.find(b) == mp.end())mp[b] = mp.size();
			E[mp[a]].push_back(P(d / 40 + t, mp[b]));
			E[mp[b]].push_back(P(d / 40 + t, mp[a]));
		}
		priority_queue<P, vector<P>, greater<P>>que;
		memset(d1, 0x3f, sizeof(d1));
		d1[0] = 0; que.push(P(0, 0));
		while (!que.empty()) {
			P p = que.top(); que.pop();
			if (d1[p.second] != p.first)continue;
			for (P u : E[p.second]) {
				if (d1[u.second] > p.first + u.first) {
					d1[u.second] = p.first + u.first;
					que.push(P(d1[u.second], u.second));
				}
			}
		}
		memset(d2, 0x3f, sizeof(d2));
		d2[1] = 0; que.push(P(0, 1));
		while (!que.empty()) {
			P p = que.top(); que.pop();
			if (d2[p.second] != p.first)continue;
			for (P u : E[p.second]) {
				if (d2[u.second] > p.first + u.first) {
					d2[u.second] = p.first + u.first;
					que.push(P(d2[u.second], u.second));
				}
			}
		}
		printf("%d\n", d1[1] + d2[2]);
	}
}
accuracy: 1
time_ms: 20
memory_kb: 3468
final_rank: 5

code_snippet: #include<bits/stdc++.h>
#define rep(i,n)for(int i=0;i<n;i++)
using namespace std;
typedef pair<int, int>P;

int d1[550], d2[550];
int main() {
	int n, m;
	while (scanf("%d%d", &n, &m), n) {
		map<string, int>mp;
		vector<P>E[550];
		string s, p, g; cin >> s >> p >> g;
		mp[s] = 0; mp[p] = 1; mp[g] = 2;
		rep(i, m) {
			string a, b; int d, t; cin >> a >> b >> d >> t;
			if (mp.find(a) == mp.end())mp[a] = mp.size();
			if (mp.find(b) == mp.end())mp[b] = mp.size();
			E[mp[a]].push_back(P(d / 40 + t, mp[b]));
			E[mp[b]].push_back(P(d / 40 + t, mp[a]));
		}
		priority_queue<P, vector<P>, greater<P>>que;
		memset(d1, 0x3f, sizeof(d1));
		d1[0] = 0; que.push(P(0, 0));
		while (!que.empty()) {
			P p = que.top(); que.pop();
			if (d1[p.second] != p.first)continue;
			for (P u : E[p.second]) {
				if (d1[u.second] > p.first + u.first) {
					d1[u.second] = p.first + u.first;
					que.push(P(d1[u.second], u.second));
				}
			}
		}
		memset(d2, 0x3f, sizeof(d2));
		d2[1] = 0; que.push(P(0, 1));
		while (!que.empty()) {
			P p = que.top(); que.pop();
			if (d2[p.second] != p.first)continue;
			for (P u : E[p.second]) {
				if (d2[u.second] > p.first + u.first) {
					d2[u.second] = p.first + u.first;
					que.push(P(d2[u.second], u.second));
				}
			}
		}
		printf("%d\n", d1[1] + d2[2]);
	}
}
accuracy: 1
time_ms: 50
memory_kb: 3400
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
int main(){
  ll n,m;
  while(cin>>n>>m,n||m){
    string s,p,g;
    cin>>s>>p>>g;
    vector<P> G[n];
    map<string,int> st;
    vector<string> vs;
    for(ll i=0;i<m;i++){
      string a,b;
      ll d,t;
      cin>>a>>b>>d>>t;
      if(st.find(a)==st.end()){
    st[a]=vs.size();
    vs.push_back(a);
      }
      if(st.find(b)==st.end()){
    st[b]=vs.size();
    vs.push_back(b);
      }
      G[st[a]].push_back(P(st[b],d/40+t));
      G[st[b]].push_back(P(st[a],d/40+t));
    }
    ll ans=0;
    ll dp[n];
    priority_queue<P,vector<P>,greater<P> > q;
    memset(dp,-1,sizeof(dp));
    q.push(P(0,st[s]));
    while(!q.empty()){
      P pp=q.top();q.pop();
      ll v=pp.second,d=pp.first;
      if(~dp[v]&&dp[v]<=d) continue;
      dp[v]=d;
      if(v==st[p]) break;
      for(ll i=0;i<(ll)G[v].size();i++){
    q.push(P(d+G[v][i].second,G[v][i].first));
      }
    }
    while(!q.empty()) q.pop();
    ans+=dp[st[p]];
    memset(dp,-1,sizeof(dp));
    q.push(P(0,st[p]));
    while(!q.empty()){
      P pp=q.top();q.pop();
      ll v=pp.second,d=pp.first;
      if(~dp[v]&&dp[v]<=d) continue;
      dp[v]=d;
      if(v==st[g]) break;
      for(ll i=0;i<(ll)G[v].size();i++){
    q.push(P(d+G[v][i].second,G[v][i].first));
      }
    }
    ans+=dp[st[g]];
    cout<<ans<<endl;
  } 
  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3432
final_rank: 7

code_snippet: #include <bits/stdc++.h>
#define N 501
#define INF 1e9
using namespace std;
typedef pair<int,int> P;
vector<P> G[N];



int dijkstra(int s,int g){
  int D[N];
  for(int i=0;i<N;i++) D[i]=INF;
  priority_queue<P,vector<P>,greater<P> > Q;
  Q.push(P(0,s));
  D[s]=0;
  while(!Q.empty()){
    P t=Q.top();Q.pop();
    int cost=t.first, pos=t.second;
    if(pos==g) return cost;
    if(D[pos]<cost) continue;
    
    for(int i=0;i<G[pos].size();i++){
      int nx=G[pos][i].first;
      int ncost=cost+G[pos][i].second;
      if(D[nx]>ncost) Q.push(P(ncost,nx)),D[nx]=ncost;
    }
  }
  cout<<"OK"<<endl;
  return -1;
}


int main(){
  while(1){
  int n,m;
  cin>>n>>m;
  if(!n&&!m)break;
  string s,p,g;
  cin>>s>>p>>g;
  map<string,int> M;
  for(int i=0;i<N;i++) G[i].clear();
  for(int i=0,d,t,cnt=0;i<m;i++) {
    string a,b;
    cin>>a>>b>>d>>t;
    if(!M.count(a)) M[a]=cnt++;
    if(!M.count(b)) M[b]=cnt++;
    G[M[a]].push_back(P(M[b],d/40+t));
    G[M[b]].push_back(P(M[a],d/40+t));
  }
  int ans= dijkstra(M[s],M[p]);
  ans=ans+dijkstra(M[p],M[g]);

  cout<<ans<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3336
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
map<string,int> ma;
void in(string s) {
  if(!ma.count(s)) {
    int k=ma.size();
    ma[s]=k;
  }
}

int main() {
  int n,m;
  while(cin >> n >> m && n) {
    ma.clear();
    string r[3];
    for(int i=0; i<3; i++) {
      cin >> r[i];
      in(r[i]);
    }
    int d[n][n];
    for(int i=0;i<n;i++){
      for(int j=0;j<n;j++)d[i][j]=1<<29;
      d[i][i]=0;
    }
    for(int i=0; i<m; i++) {
      string s,t;
      int b,c;
      cin >> s >> t >> b >> c;
      in(s);in(t);
      d[ma[s]][ma[t]]=b/40+c;
      d[ma[t]][ma[s]]=b/40+c;
    }
    for(int k=0;k<n;k++)for(int i=0;i<n;i++)for(int j=0;j<n;j++)d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
    cout << d[ma[r[0]]][ma[r[1]]]+d[ma[r[1]]][ma[r[2]]] << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 310
memory_kb: 4076
final_rank: 17

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
int main(){
  ll n,m;
  while(cin>>n>>m,n||m){
    string s,p,g;
    cin>>s>>p>>g;
    vector<P> G[n];
    map<string,int> st;
    vector<string> vs;
    for(ll i=0;i<m;i++){
      string a,b;
      ll d,t;
      cin>>a>>b>>d>>t;
      if(st.find(a)==st.end()){
	st[a]=vs.size();
	vs.push_back(a);
      }
      if(st.find(b)==st.end()){
	st[b]=vs.size();
	vs.push_back(b);
      }
      G[st[a]].push_back(P(st[b],d/40+t));
      G[st[b]].push_back(P(st[a],d/40+t));
    }
    ll ans=0;
    ll dp[n];
    priority_queue<P,vector<P>,greater<P> > q;
    memset(dp,-1,sizeof(dp));
    q.push(P(0,st[s]));
    while(!q.empty()){
      P pp=q.top();q.pop();
      ll v=pp.second,d=pp.first;
      if(~dp[v]&&dp[v]<=d) continue;
      dp[v]=d;
      if(v==st[p]) break;
      for(ll i=0;i<(ll)G[v].size();i++){
	q.push(P(d+G[v][i].second,G[v][i].first));
      }
    }
    while(!q.empty()) q.pop();
    ans+=dp[st[p]];
    memset(dp,-1,sizeof(dp));
    q.push(P(0,st[p]));
    while(!q.empty()){
      P pp=q.top();q.pop();
      ll v=pp.second,d=pp.first;
      if(~dp[v]&&dp[v]<=d) continue;
      dp[v]=d;
      if(v==st[g]) break;
      for(ll i=0;i<(ll)G[v].size();i++){
	q.push(P(d+G[v][i].second,G[v][i].first));
      }
    }
    ans+=dp[st[g]];
    cout<<ans<<endl;
  } 
  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3424
final_rank: 6

code_snippet: #include <iostream>
#include <map>
#include <algorithm>
 
using namespace std;
 
const int MAX = 500;
const int INF = 1e9;
 
int main(){
    int n,m;
 
    while(cin >> n >> m, n | m){
	map<string,int> mp;
	int dist[MAX+1][MAX+1];
	string a,b,start,goal,via;
	int c,d;
 
	for(int i = 0 ; i <= n ; i++){
	    for(int j = 0 ; j <= n ; j++){
		dist[i][j] = INF;
	    }
	}
 
	cin >> start >> via >> goal;
 
	int s = 1;
	for(int i = 0 ; i < m ; i++){
	    cin >> a >> b >> c >> d;
 
	    if(!mp[a]){
		mp[a] = s++;
	    }
	    if(!mp[b]){ 
		mp[b] = s++;
	    }
 
	    dist[mp[a]][mp[b]] = dist[mp[b]][mp[a]] = c / 40 + d;
	}
   
	for(int k = 1 ; k <= n ; k++){
	    for(int i = 1 ; i <= n ; i++){
		for(int j = 1 ; j <= n ; j++){
		    dist[i][j] = min(dist[i][j] ,dist[i][k] + dist[k][j]);
		}
	    }
	}
	cout << dist[mp[start]][mp[via]] + dist[mp[via]][mp[goal]] << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 330
memory_kb: 4148
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;
string S[5000],T[5000],V[5000],A,B,C;int a[5000],b[5000],n,m,dist[5000];
vector<string>U;vector<pair<int,int>>x[500];
int dfs(int s,int g){
	for(int i=0;i<5000;i++)dist[i]=1<<30;
	dist[s]=0;
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			for(int k=0;k<x[j].size();k++){
				dist[x[j][k].first]=min(dist[x[j][k].first],dist[j]+x[j][k].second);
			}
		}
	}
	return dist[g];
}
int main(){
	while(true){
		cin>>n>>m;for(int i=0;i<500;i++)x[i].clear();
		if(n==0){break;}U.clear();cin>>A>>B>>C;
		for(int i=0;i<m;i++){
			cin>>S[i]>>T[i]>>a[i]>>b[i];
			U.push_back(S[i]);U.push_back(T[i]);
		}
		sort(U.begin(),U.end());V[0]=U[0];int cnt=1,G,H,I;
		for(int i=1;i<U.size();i++){
			if(U[i]!=U[i-1]){V[cnt]=U[i];cnt++;}
		}
		for(int i=0;i<cnt;i++){
			if(A==V[i])G=i;
			if(B==V[i])H=i;
			if(C==V[i])I=i;
		}
		for(int i=0;i<m;i++){
			int s1=0,t1=0;
			for(int j=0;j<cnt;j++){
				if(S[i]==V[j])s1=j;
				if(T[i]==V[j])t1=j;
			}
			x[s1].push_back(make_pair(t1,a[i]/40+b[i]));
			x[t1].push_back(make_pair(s1,a[i]/40+b[i]));
		}
		cout<<dfs(G,H)+dfs(H,I)<<endl;
	}
	return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 3900
final_rank: 15

code_snippet: #include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<map>
#include<set>
#include<utility>
#include<cmath>
#include<cstring>
#include<queue>
#include<cstdio>
#define loop(i,a,b) for(int i=a;i<b;i++) 
#define rep(i,a) loop(i,0,a)
#define pb push_back
#define mp make_pair
#define all(in) in.begin(),in.end()
const double PI=acos(-1);
const double EPS=1e-10;
const int inf=1e9;
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> pii;
int main(){
	int n,q;
	while(cin>>n>>q,n+q){
		string s,p,g;
		cin>>s>>p>>g;
		map<string,int>m;
		int co=1;
		vvi cost(n+1,vi(n+1,inf));
		while(q--){
			string a,b;
			int d,t;
			cin>>a>>b>>d>>t;
			if(m[a]==0)m[a]=co++;
			if(m[b]==0)m[b]=co++;
			cost[m[a]][m[b]]=cost[m[b]][m[a]]=d/40+t;
		}
		rep(k,n+1)rep(i,n+1)rep(j,n+1)
			cost[i][j]=min(cost[i][j],cost[i][k]+cost[k][j]);
		cout<<cost[m[s]][m[p]]+cost[m[p]][m[g]]<<endl;
	}
}
accuracy: 1
time_ms: 570
memory_kb: 2296
final_rank: 16

code_snippet: #include<bits/stdc++.h>
using namespace std;
struct edge{
  int to, cost;
};
typedef pair<int, int> pii;//cost vertex
typedef pair<int ,pii> piii;//cost vertex state
int main(int argc, char *argv[]){
  int n, m;
  while(cin >> n >> m, n){
    string s, p, goal;
    map<string, int> msi;
    cin >> s >> p >> goal;
    msi[s] = msi.size() - 1;
    msi[p] = msi.size() - 1;
    msi[goal] = msi.size() - 1;
    int S = msi[s], P = msi[p], GOAL = msi[goal];
    vector<vector<edge> > g(n, vector<edge>());
    vector<vector<int> > dp(2, vector<int>(n, 1e9));
    for (int i = 0; i < m; i++) {
      int d, t, from, to;
      string a, b;
      cin >> a >> b >> d >> t;
      if(msi.find(a) == msi.end())
        msi[a] = msi.size() - 1;
      if(msi.find(b) == msi.end())
        msi[b] = msi.size() - 1;
      to = msi[a];
      from = msi[b];
      //std::cout << "to:" << to << " from:" << from << std::endl;
      g[to].push_back(edge{from, d/40 + t});
      g[from].push_back(edge{to, d/40 + t});
    }
    priority_queue<piii, vector<piii>, greater<piii> > que;
    que.push(piii(0, pii(S, 0)));
    dp[0][S] = 0;
    while(!que.empty()){
      int v = que.top().second.first;
      int c = que.top().first;
      int state = que.top().second.second;
      que.pop();
      for (int i = 0; i < g[v].size(); i++) {
        int st = state;
        edge e = g[v][i];
        if(dp[state][e.to] > c + e.cost){
          if(e.to == P)st = 1;
          dp[state][e.to] = c + e.cost;
          que.push(piii(c + e.cost, pii(e.to, st)));
        }
      }
    }
    std::cout << dp[1][GOAL] << std::endl;
  }
  return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 1504
final_rank: 1