Problem:
自転車でダイエット
A さんは甘いものが大好きですが、最近は奥さんからダイエットするように言われています。ある日、A さんが自宅から市役所に出かけるとき、奥さんは自転車で行くことを勧めました。そこでA さんはしぶしぶ自転車に乗って出かけましたが、甘い物の好きな A さんは、途中にあるケーキ屋さんに立ち寄りケーキの食べ歩きをしようと思いつきました。
自転車をこげば走行距離に応じてカロリーが消費されますが、ケーキを食べればその分カロリーが摂取されます。正味の消費カロリーは、自転車をこいで消費したカロリーからケーキを食べて摂取したカロリーを引いた値になります。したがって、正味の消費カロリーが 0 より小さくなることもあります。
ケーキ屋さんでケーキを買ったら、 Aさんはその場でケーキを全部食べてしまいます。 Aさんがすべてのケーキ屋さんに立ち寄るとは限りませんが、ケーキ屋さんが存在する地点を通るときには、必ず立ち寄ってケーキを 1 つ買って食べるものとします。ただし、同じケーキ屋さんの前を何度も通るのはさすがに気がひけるので、各ケーキ屋さんに訪れられるのは 1 回だけとします。また、目的地の市役所をいったん通り過ぎてからケーキ屋さんに立ち寄り、その後で市役所に戻って用を済ませてもよいものとし、ケーキ屋さん以外は何度訪れても良いものとします。
A さんの自宅から市役所までの地図情報と、その途中にあるケーキ屋さんで食べられるケーキのカロリーの一覧、単位距離の走行による消費カロリーを入力とし、自宅を出発してから市役所に入るまでの正味の消費カロリーの最小値を出力するプログラムを作成してください。
地図には、A さんの自宅と市役所、ケーキ屋さんとランドマーク(目印)になる建物が書かれています。地図を表す入力データは、A さんの自宅、市役所、ケーキ屋さんとランドマークの各地点の間をつなぐ道があるとき、2 つの地点を表す記号とその間の距離からなる行を含みます。たとえば、5 番目のケーキ屋さんと 3 番目のランドマークの間の距離が 10 なら、入力データは以下のような行を含みます。
C5 L3 10
このようにケーキ屋さんには C、ランドマークには L を番号の前につけて表します。また、A さんの自宅は H、市役所は D で表します。入力データに 2 つの地点とその間の距離が与えられているなら、2 地点の間をどちら向きにも進めます。たとえば、上の例ではケーキ屋さんからランドマークへも、その逆向きへも進むことができます。また、自宅から市役所までは必ずたどり着けるものとします。それ以外に与えられる入力データは、ケーキ屋さんの数
m
、ランドマークの数
n
、単位距離あたりの消費カロリー
k
、 1 番目のケーキ屋さんから
m
番目のケーキ屋さんまでのそれぞれで買えるケーキのカロリーを表す
m
個のデータ、距離のデータの総数
d
です。
Input
複数のデータセットの並びが入力として与えられます。入力の終わりは四つの 0 の行で示されます。
  各データセットは以下の形式で与えられます。
m
n
k
d
c
1
c
2
...
c
m
s
1
t
1
e
1
s
2
t
2
e
2
:
s
d
t
d
e
d
1 行目にケーキ屋さんの数
m
(1 ≤
m
≤ 6)、 ランドマークの数
n
(1 ≤
n
≤ 100) 、単位距離あたりの消費カロリー
k
(1 ≤
k
≤ 5)、距離のデータの総数
d
(5 ≤
d
≤ 256) が与えられます。
2 行目に各ケーキ屋で買うケーキのカロリー
c
i
(1 ≤
c
i
≤ 100) が与えられます。
続く
d
行に
i
番目の 2 つの地点間の距離データ
s
i
,
t
i
,
e
i
(1 ≤
e
i
≤ 20)  が与えられます。
データセットの数は 100 を超えません。
Output
入力データセットごとに、全体の消費カロリーの最小値を１行に出力します。
Sample Input
1 1 2 5
35
H L1 5
C1 D 6
C1 H 12
L1 D 10
C1 L1 20
2 1 4 6
100 70
H L1 5
C1 L1 12
C1 D 11
C2 L1 7
C2 D 15
L1 D 8
0 0 0 0
Output for the Sample Input
1
-2

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;

constexpr int INF = 1e9;

struct edge {
    int from, to, weight;
};

int main() {
    int m, n, k, d;
    while(cin >> m >> n >> k >> d, m) {
        vector<int> c(m);
        for(int i=0; i<m; ++i) {
            cin >> c[i];
        }
        auto get_id = [m, n](string const& s) {
            if(s[0] == 'H') {
                return 0;
            } else if(s[0] == 'C') {
                return s[1] - '0';
            } else if(s[0] == 'L') {
                return stoi(s.substr(1)) + m;
            } else {
                return m+n+1;
            }
        };
        vector<vector<int>> cost(1 << m, vector<int>(m+n+2, INF));
        vector<edge> es;
        for(int i=0; i<d; ++i) {
            string s, t;
            int e;
            cin >> s >> t >> e;
            int a = get_id(s), b = get_id(t);
            es.push_back((edge){a, b, e*k});
            es.push_back((edge){b, a, e*k});
        }

        cost[0][0] = 0;
        while(true) {
            bool update = false;
            for(int i=0; i<(1<<m); ++i) {
                for(int j=0; j<2*d; ++j) {
                    edge e = es[j];
                    if(cost[i][e.from] == INF) {
                        continue;
                    }
                    if(1 <= e.to && e.to <= m) {
                        if(!(i >> (e.to - 1) & 1) && cost[i | 1 << (e.to - 1)][e.to] > cost[i][e.from] + e.weight - c[e.to-1]) {
                            cost[i | 1 << (e.to - 1)][e.to] = cost[i][e.from] + e.weight - c[e.to-1];
                            update = true;
                        }        
                    } else if(cost[i][e.to] > cost[i][e.from] + e.weight) {
                        cost[i][e.to] = cost[i][e.from] + e.weight;
                        update = true;
                    }
                }
            }
            if(!update) {
                break;
            }
        }
        int res = INF;
        for(int i=0; i<(1<<m); ++i) {
            res = min(res, cost[i][m+n+1]);
        }
        cout << res << endl;
    }
}
accuracy: 1
time_ms: 40
memory_kb: 3448
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int m, n, k, d, e, v, u, w, S;
    while(cin >> m >> n >> k >> d, m){
        vector<int> c(m);
        for(auto &&v:c)cin >> v;
        auto f = [&](string s){
            if(s[0] == 'C')return stoi(s.substr(1, s.size() - 1)) - 1;
            if(s[0] == 'L')return stoi(s.substr(1, s.size() - 1)) - 1 + m;
            if(s == "H")return m + n;
            return m + n + 1;
        };
        vector<vector<pair<int,int>>> g(n + m + 2);
        string s, t;
        while(d--){
            cin >> s >> t >> e;
            g[f(s)].emplace_back(f(t), k * e);
            g[f(t)].emplace_back(f(s), k * e);
        }
        priority_queue<tuple<int,int>, vector<tuple<int,int,int>>, greater<tuple<int,int,int>>> pq;
        vector<vector<int>> dp(n + m + 2, vector<int>(1 << m, 1 << 30));
        pq.emplace(0, n + m, 0);
        dp[n + m][0] = 0;
        while(!pq.empty()){
            tie(d, v, S) = pq.top();
            pq.pop();
            if(d > dp[v][S])continue;
            for(auto &&pa:g[v]){
                tie(u, w) = pa;
                int T = S;
                if(u < m){
                    if(S >> u & 1)continue;
                    T |= 1 << u;
                }
                if(dp[v][S] + w >= dp[u][T])continue;
                dp[u][T] = dp[v][S] + w;
                pq.emplace(dp[u][T], u, T);
            }
        }
        int ans = 1 << 30;
        for(int i = 0; i < (1 << m); i++){
            int sumv = 0;
            for(int j = 0; j < m; j++){
                if(i >> j & 1)sumv -= c[j];
            }
            sumv += dp.back()[i];
            ans = min(ans, sumv);
        }
        cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 30
memory_kb: 3336
final_rank: 11

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define SIZE 205
#define MAX 7

struct Edge{
	void set(int arg_from,int arg_to,int arg_dist){
		from = arg_from;
		to = arg_to;
		dist = arg_dist;
	}
	int from,to,dist;
};

int POW[MAX];
int value[6];
int num_cake,num_land,k,E;
int index_cake[6],index_land[105],rev_cake[SIZE];
int min_dist[SIZE][64];
bool is_cake[SIZE];
Edge edge[1000];


void func(){

	for(int i = 0; i < SIZE; i++){

		is_cake[i] = false;
	}

	int start = 0,goal = 1;
	int index = 2;
	for(int i = 0; i < num_cake; i++){

		is_cake[index] = true;
		rev_cake[index] = i;
		index_cake[i] = index++;
	}
	for(int i = 0; i < num_land; i++){

		index_land[i] = index++;
	}

	for(int i = 0; i < num_cake; i++){

		scanf("%d",&value[i]);
	}

	char A[10],B[10];
	int from,to;
	int dist,tmp;

	int num_edge = 0;

	for(int loop = 0; loop < E; loop++){

		scanf("%s %s %d",A,B,&dist);

		switch(A[0]){
		case 'C':
			tmp = 0;
			for(int i = 1; A[i] != '\0'; i++){

				tmp = 10*tmp+(A[i]-'0');
			}
			tmp--;
			from = index_cake[tmp];

			break;
		case 'L':
			tmp = 0;
			for(int i = 1; A[i] != '\0'; i++){

				tmp = 10*tmp+(A[i]-'0');
			}
			tmp--;
			from = index_land[tmp];

			break;
		case 'H':
			from = start;
			break;
		case 'D':
			from = goal;
			break;
		}


		switch(B[0]){
		case 'C':
			tmp = 0;
			for(int i = 1; B[i] != '\0'; i++){

				tmp = 10*tmp+(B[i]-'0');
			}
			tmp--;
			to = index_cake[tmp];

			break;
		case 'L':
			tmp = 0;
			for(int i = 1; B[i] != '\0'; i++){

				tmp = 10*tmp+(B[i]-'0');
			}
			tmp--;
			to = index_land[tmp];

			break;
		case 'H':
			to = start;
			break;
		case 'D':
			to = goal;
			break;
		}

		int work_cost = k*dist;
		if(is_cake[from]){

			int tmp_index = rev_cake[from];
			work_cost -= value[tmp_index];

		}

		edge[num_edge++].set(from,to,work_cost);

		work_cost = k*dist;
		if(is_cake[to]){

			int tmp_index = rev_cake[to];
			work_cost -= value[tmp_index];
		}

		edge[num_edge++].set(to,from,work_cost);
	}

	for(int i = 0; i < index; i++){
		for(int k = 0; k < POW[num_cake]; k++){

			min_dist[i][k] = BIG_NUM;
		}
	}

	min_dist[start][0] = 0;

	bool updated;

	//負辺を持つのでベルマンフォード

	for(int i = 0; i < index; i++){
		updated = false;
		for(int k = 0; k < num_edge; k++){
			Edge e = edge[k];
			for(int state = 0; state < POW[num_cake]; state++){
				if(min_dist[e.from][state] == BIG_NUM)continue;

				int next_node = e.to;
				int next_state = state;
				if(is_cake[e.to]){
					int tmp_index = rev_cake[e.to];
					if(state & POW[tmp_index])continue;

					next_state = state+POW[tmp_index];
				}
				int next_dist = min_dist[e.from][state]+e.dist;

				if(min_dist[next_node][next_state] > next_dist){
					min_dist[next_node][next_state] = next_dist;
					updated = true;
				}
			}
		}
		if(!updated)break;
	}

	int ans = BIG_NUM;
	for(int state = 0; state < POW[num_cake]; state++){

		ans = min(ans,min_dist[goal][state]);
	}

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

int main(){

	POW[0] = 1;
	for(int i = 1; i < MAX; i++){

		POW[i] = POW[i-1]*2;
	}

	while(true){

		scanf("%d %d %d %d",&num_cake,&num_land,&k,&E);
		if(num_cake == 0)break;


		func();
	}

	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3260
final_rank: 8

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define SIZE 205
#define MAX 7

struct Edge{
	void set(int arg_from,int arg_to,int arg_dist){
		from = arg_from;
		to = arg_to;
		dist = arg_dist;
	}
	int from,to,dist;
};

int POW[MAX];
int value[6];
int num_cake,num_land,k,E;
int index_cake[6],index_land[105],rev_cake[SIZE];
int min_dist[SIZE][64];
bool is_cake[SIZE];
Edge edge[1000];


void func(){

	for(int i = 0; i < SIZE; i++){

		is_cake[i] = false;
	}

	int start = 0,goal = 1;
	int index = 2;
	for(int i = 0; i < num_cake; i++){

		is_cake[index] = true;
		rev_cake[index] = i;
		index_cake[i] = index++;
	}
	for(int i = 0; i < num_land; i++){

		index_land[i] = index++;
	}

	for(int i = 0; i < num_cake; i++){

		scanf("%d",&value[i]);
	}

	char A[10],B[10];
	int from,to;
	int dist,tmp;

	int num_edge = 0;

	for(int loop = 0; loop < E; loop++){

		scanf("%s %s %d",A,B,&dist);

		switch(A[0]){
		case 'C':
			tmp = 0;
			for(int i = 1; A[i] != '\0'; i++){

				tmp = 10*tmp+(A[i]-'0');
			}
			tmp--;
			from = index_cake[tmp];

			break;
		case 'L':
			tmp = 0;
			for(int i = 1; A[i] != '\0'; i++){

				tmp = 10*tmp+(A[i]-'0');
			}
			tmp--;
			from = index_land[tmp];

			break;
		case 'H':
			from = start;
			break;
		case 'D':
			from = goal;
			break;
		}


		switch(B[0]){
		case 'C':
			tmp = 0;
			for(int i = 1; B[i] != '\0'; i++){

				tmp = 10*tmp+(B[i]-'0');
			}
			tmp--;
			to = index_cake[tmp];

			break;
		case 'L':
			tmp = 0;
			for(int i = 1; B[i] != '\0'; i++){

				tmp = 10*tmp+(B[i]-'0');
			}
			tmp--;
			to = index_land[tmp];

			break;
		case 'H':
			to = start;
			break;
		case 'D':
			to = goal;
			break;
		}

		int work_cost = k*dist;
		if(is_cake[from]){

			int tmp_index = rev_cake[from];
			work_cost -= value[tmp_index];

		}

		edge[num_edge++].set(from,to,work_cost);

		work_cost = k*dist;
		if(is_cake[to]){

			int tmp_index = rev_cake[to];
			work_cost -= value[tmp_index];
		}

		edge[num_edge++].set(to,from,work_cost);
	}

	for(int i = 0; i < index; i++){
		for(int k = 0; k < POW[num_cake]; k++){

			min_dist[i][k] = BIG_NUM;
		}
	}

	min_dist[start][0] = 0;

	bool updated;

	for(int i = 0; i < index; i++){
		updated = false;
		for(int k = 0; k < num_edge; k++){
			Edge e = edge[k];
			for(int state = 0; state < POW[num_cake]; state++){
				if(min_dist[e.from][state] == BIG_NUM)continue;

				int next_node = e.to;
				int next_state = state;
				if(is_cake[e.to]){
					int tmp_index = rev_cake[e.to];
					if(state & POW[tmp_index])continue;

					next_state = state+POW[tmp_index];
				}
				int next_dist = min_dist[e.from][state]+e.dist;

				if(min_dist[next_node][next_state] > next_dist){
					min_dist[next_node][next_state] = next_dist;
					updated = true;
				}
			}
		}
		if(!updated)break;
	}

	int ans = BIG_NUM;
	for(int state = 0; state < POW[num_cake]; state++){

		ans = min(ans,min_dist[goal][state]);
	}

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

int main(){

	POW[0] = 1;
	for(int i = 1; i < MAX; i++){

		POW[i] = POW[i-1]*2;
	}

	while(true){

		scanf("%d %d %d %d",&num_cake,&num_land,&k,&E);
		if(num_cake == 0)break;


		func();
	}

	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3160
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using VI = vector<int>;
using VL = vector<ll>;
using VS = vector<string>;
template<class T> using PQ = priority_queue<T, vector<T>, greater<T>>;
#define FOR(i,a,n) for(int i=(a);i<(n);++i)
#define eFOR(i,a,n) for(int i=(a);i<=(n);++i)
#define rFOR(i,a,n) for(int i=(n)-1;i>=(a);--i)
#define erFOR(i,a,n) for(int i=(n);i>=(a);--i)
#define SORT(a) sort(a.begin(),a.end())
#define rSORT(a) sort(a.rbegin(),a.rend())
#define fSORT(a,f) sort(a.begin(),a.end(),f)
#define all(a) a.begin(),a.end()
#define out(y,x) ((y)<0||h<=(y)||(x)<0||w<=(x))
#define tp(a,i) get<i>(a)
#ifdef _DEBUG
#define line cout << "-----------------------------\n"
#define stop system("pause")
#endif
constexpr ll INF = 1000000000;
constexpr ll LLINF = 1LL << 60;
constexpr ll mod = 1000000007;
constexpr ll MOD = 998244353;
constexpr ld eps = 1e-10;
constexpr ld pi = 3.1415926535897932;
template<class T>inline bool chmax(T& a, const T& b) { if (a < b) { a = b; return true; }return false; }
template<class T>inline bool chmin(T& a, const T& b) { if (a > b) { a = b; return true; }return false; }
inline void init() { cin.tie(nullptr); cout.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(15); }
template<class T>inline istream& operator>>(istream& is, vector<T>& v) { for (auto& a : v)is >> a; return is; }
template<class T, class U>inline istream& operator>>(istream& is, pair<T, U>& p) { is >> p.first >> p.second; return is; }
template<class T>inline vector<T> vec(size_t a) { return vector<T>(a); }
template<class T>inline vector<T> defvec(T def, size_t a) { return vector<T>(a, def); }
template<class T, class... Ts>inline auto vec(size_t a, Ts... ts) { return vector<decltype(vec<T>(ts...))>(a, vec<T>(ts...)); }
template<class T, class... Ts>inline auto defvec(T def, size_t a, Ts... ts) { return vector<decltype(defvec<T>(def, ts...))>(a, defvec<T>(def, ts...)); }
template<class T>inline void print(const T& a) { cout << a << "\n"; }
template<class T, class... Ts>inline void print(const T& a, const Ts&... ts) { cout << a << " "; print(ts...); }
template<class T>inline void print(const vector<T>& v) { for (int i = 0; i < v.size(); ++i)cout << v[i] << (i == v.size() - 1 ? "\n" : " "); }
template<class T>inline void print(const vector<vector<T>>& v) { for (auto& a : v)print(a); }
inline string reversed(const string& s) { string t = s; reverse(all(t)); return t; }
template<class T>inline T sum(const vector<T>& a, int l, int r) { return a[r] - (l == 0 ? 0 : a[l - 1]); }
template<class T>inline void END(T s) { print(s); exit(0); }
void END() { exit(0); }

int m, n;
int parse(string s) {
    if (s == "H")return m + n;
    if (s == "D")return m + n + 1;
    return stoi(s.substr(1)) + (s[0] == 'C' ? 0 : m) - 1;
}

int main() {
    init();

    for (int k, d; cin >> m >> n >> k >> d, m;) {
        int v = m + n + 2;
        VI c(m); cin >> c;
        VI a(d * 2), b(d * 2), e(d * 2);
        FOR(i, 0, d) {
            string s, t; cin >> s >> t >> e[i];
            a[i] = parse(s), b[i] = parse(t);
            e[i] *= k;
            a[d + i] = b[i], b[d + i] = a[i], e[d + i] = e[i];
        }

        int start = v - 2, goal = v - 1;
        auto dp = defvec<int>(INF, 1 << m, v);
        dp[0][start] = 0;
        bool f = true;;
        for (int _ = 0; _ < (1 << m) * v && f; ++_) {
            f = false;
            FOR(bit, 0, 1 << m)FOR(i, 0, d * 2) {
                if (dp[bit][a[i]] == INF)continue;
                if (b[i] < m) {
                    if (!(bit & (1 << b[i])))f |= chmin(dp[bit | (1 << b[i])][b[i]], dp[bit][a[i]] + e[i] - c[b[i]]);
                }
                else f |= chmin(dp[bit][b[i]], dp[bit][a[i]] + e[i]);
            }
        }

        int ans = INF;
        FOR(i, 0, 1 << m)chmin(ans, dp[i][goal]);
        print(ans);
    }
    

    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3436
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using VI = vector<int>;
using VL = vector<ll>;
using VS = vector<string>;
template<class T> using PQ = priority_queue<T, vector<T>, greater<T>>;
#define FOR(i,a,n) for(int i=(a);i<(n);++i)
#define eFOR(i,a,n) for(int i=(a);i<=(n);++i)
#define rFOR(i,a,n) for(int i=(n)-1;i>=(a);--i)
#define erFOR(i,a,n) for(int i=(n);i>=(a);--i)
#define SORT(a) sort(a.begin(),a.end())
#define rSORT(a) sort(a.rbegin(),a.rend())
#define fSORT(a,f) sort(a.begin(),a.end(),f)
#define all(a) a.begin(),a.end()
#define out(y,x) ((y)<0||h<=(y)||(x)<0||w<=(x))
#define tp(a,i) get<i>(a)
#ifdef _DEBUG
#define line cout << "-----------------------------\n"
#define stop system("pause")
#endif
constexpr ll INF = 1000000000;
constexpr ll LLINF = 1LL << 60;
constexpr ll mod = 1000000007;
constexpr ll MOD = 998244353;
constexpr ld eps = 1e-10;
constexpr ld pi = 3.1415926535897932;
template<class T>inline bool chmax(T& a, const T& b) { if (a < b) { a = b; return true; }return false; }
template<class T>inline bool chmin(T& a, const T& b) { if (a > b) { a = b; return true; }return false; }
inline void init() { cin.tie(nullptr); cout.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(15); }
template<class T>inline istream& operator>>(istream& is, vector<T>& v) { for (auto& a : v)is >> a; return is; }
template<class T, class U>inline istream& operator>>(istream& is, pair<T, U>& p) { is >> p.first >> p.second; return is; }
template<class T>inline vector<T> vec(size_t a) { return vector<T>(a); }
template<class T>inline vector<T> defvec(T def, size_t a) { return vector<T>(a, def); }
template<class T, class... Ts>inline auto vec(size_t a, Ts... ts) { return vector<decltype(vec<T>(ts...))>(a, vec<T>(ts...)); }
template<class T, class... Ts>inline auto defvec(T def, size_t a, Ts... ts) { return vector<decltype(defvec<T>(def, ts...))>(a, defvec<T>(def, ts...)); }
template<class T>inline void print(const T& a) { cout << a << "\n"; }
template<class T, class... Ts>inline void print(const T& a, const Ts&... ts) { cout << a << " "; print(ts...); }
template<class T>inline void print(const vector<T>& v) { for (int i = 0; i < v.size(); ++i)cout << v[i] << (i == v.size() - 1 ? "\n" : " "); }
template<class T>inline void print(const vector<vector<T>>& v) { for (auto& a : v)print(a); }
inline string reversed(const string& s) { string t = s; reverse(all(t)); return t; }
template<class T>inline T sum(const vector<T>& a, int l, int r) { return a[r] - (l == 0 ? 0 : a[l - 1]); }
template<class T>inline void END(T s) { print(s); exit(0); }
void END() { exit(0); }

int m, n;
int parse(string s) {
    if (s == "H")return m + n;
    if (s == "D")return m + n + 1;
    return stoi(s.substr(1)) + (s[0] == 'C' ? 0 : m) - 1;
}

int main() {
    init();

    for (int k, d; cin >> m >> n >> k >> d, m;) {
        int v = m + n + 2;
        VI c(m); cin >> c;
        VI a(d * 2), b(d * 2), e(d * 2);
        FOR(i, 0, d) {
            string s, t; cin >> s >> t >> e[i];
            a[i] = parse(s), b[i] = parse(t);
            e[i] *= k;
            a[d + i] = b[i], b[d + i] = a[i], e[d + i] = e[i];
        }

        int start = v - 2, goal = v - 1;
        auto dp = defvec<int>(INF, 1 << m, v);
        dp[0][start] = 0;
        for (bool f = true; f;) {
            f = false;
            FOR(bit, 0, 1 << m)FOR(i, 0, d * 2) {
                if (dp[bit][a[i]] == INF)continue;
                if (b[i] < m) {
                    if (!(bit & (1 << b[i])))f |= chmin(dp[bit | (1 << b[i])][b[i]], dp[bit][a[i]] + e[i] - c[b[i]]);
                }
                else f |= chmin(dp[bit][b[i]], dp[bit][a[i]] + e[i]);
            }
        }

        int ans = INF;
        FOR(i, 0, 1 << m)chmin(ans, dp[i][goal]);
        print(ans);
    }
    

    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3440
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using VI = vector<int>;
using VL = vector<ll>;
using VS = vector<string>;
template<class T> using PQ = priority_queue<T, vector<T>, greater<T>>;
#define FOR(i,a,n) for(int i=(a);i<(n);++i)
#define eFOR(i,a,n) for(int i=(a);i<=(n);++i)
#define rFOR(i,a,n) for(int i=(n)-1;i>=(a);--i)
#define erFOR(i,a,n) for(int i=(n);i>=(a);--i)
#define SORT(a) sort(a.begin(),a.end())
#define rSORT(a) sort(a.rbegin(),a.rend())
#define fSORT(a,f) sort(a.begin(),a.end(),f)
#define all(a) a.begin(),a.end()
#define out(y,x) ((y)<0||h<=(y)||(x)<0||w<=(x))
#define tp(a,i) get<i>(a)
#ifdef _DEBUG
#define line cout << "-----------------------------\n"
#define stop system("pause")
#endif
constexpr ll INF = 1000000000;
constexpr ll LLINF = 1LL << 60;
constexpr ll mod = 1000000007;
constexpr ll MOD = 998244353;
constexpr ld eps = 1e-10;
constexpr ld pi = 3.1415926535897932;
template<class T>inline bool chmax(T& a, const T& b) { if (a < b) { a = b; return true; }return false; }
template<class T>inline bool chmin(T& a, const T& b) { if (a > b) { a = b; return true; }return false; }
inline void init() { cin.tie(nullptr); cout.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(15); }
template<class T>inline istream& operator>>(istream& is, vector<T>& v) { for (auto& a : v)is >> a; return is; }
template<class T, class U>inline istream& operator>>(istream& is, pair<T, U>& p) { is >> p.first >> p.second; return is; }
template<class T>inline vector<T> vec(size_t a) { return vector<T>(a); }
template<class T>inline vector<T> defvec(T def, size_t a) { return vector<T>(a, def); }
template<class T, class... Ts>inline auto vec(size_t a, Ts... ts) { return vector<decltype(vec<T>(ts...))>(a, vec<T>(ts...)); }
template<class T, class... Ts>inline auto defvec(T def, size_t a, Ts... ts) { return vector<decltype(defvec<T>(def, ts...))>(a, defvec<T>(def, ts...)); }
template<class T>inline void print(const T& a) { cout << a << "\n"; }
template<class T, class... Ts>inline void print(const T& a, const Ts&... ts) { cout << a << " "; print(ts...); }
template<class T>inline void print(const vector<T>& v) { for (int i = 0; i < v.size(); ++i)cout << v[i] << (i == v.size() - 1 ? "\n" : " "); }
template<class T>inline void print(const vector<vector<T>>& v) { for (auto& a : v)print(a); }
inline string reversed(const string& s) { string t = s; reverse(all(t)); return t; }
template<class T>inline T sum(const vector<T>& a, int l, int r) { return a[r] - (l == 0 ? 0 : a[l - 1]); }
template<class T>inline void END(T s) { print(s); exit(0); }
void END() { exit(0); }

int m, n;
int parse(string s) {
    if (s == "H")return m + n;
    if (s == "D")return m + n + 1;
    return stoi(s.substr(1)) + (s[0] == 'C' ? 0 : m) - 1;
}

int main() {
    init();

    for (int k, d; cin >> m >> n >> k >> d, m;) {
        int v = m + n + 2;
        VI c(m); cin >> c;
        vector<vector<pair<int, int>>> g(v);
        FOR(i, 0, d) {
            string s, t; int e; cin >> s >> t >> e;
            int a = parse(s), b = parse(t);
            e *= k;
            g[a].emplace_back(b, e);
            g[b].emplace_back(a, e);
        }

        int start = v - 2, goal = v - 1;
        auto dp = defvec<int>(INF, 1 << m, v);
        dp[0][start] = 0;
        for (bool f = true; f;) {
            f = false;
            FOR(bit, 0, 1 << m)FOR(cur, 0, v) {
                if (dp[bit][cur] == INF)continue;
                for (auto [to, cost] : g[cur]) {
                    if (to < m) {
                        if (!(bit & (1 << to)))f |= chmin(dp[bit | (1 << to)][to], dp[bit][cur] + cost - c[to]);
                    }
                    else f |= chmin(dp[bit][to], dp[bit][cur] + cost);
                }
            }
        }

        int ans = INF;
        FOR(i, 0, 1 << m)chmin(ans, dp[i][goal]);
        print(ans);
    }
    

    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3288
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using VI = vector<int>;
using VL = vector<ll>;
using VS = vector<string>;
template<class T> using PQ = priority_queue<T, vector<T>, greater<T>>;
#define FOR(i,a,n) for(int i=(a);i<(n);++i)
#define eFOR(i,a,n) for(int i=(a);i<=(n);++i)
#define rFOR(i,a,n) for(int i=(n)-1;i>=(a);--i)
#define erFOR(i,a,n) for(int i=(n);i>=(a);--i)
#define SORT(a) sort(a.begin(),a.end())
#define rSORT(a) sort(a.rbegin(),a.rend())
#define fSORT(a,f) sort(a.begin(),a.end(),f)
#define all(a) a.begin(),a.end()
#define out(y,x) ((y)<0||h<=(y)||(x)<0||w<=(x))
#define tp(a,i) get<i>(a)
#ifdef _DEBUG
#define line cout << "-----------------------------\n"
#define stop system("pause")
#endif
constexpr ll INF = 1000000000;
constexpr ll LLINF = 1LL << 60;
constexpr ll mod = 1000000007;
constexpr ll MOD = 998244353;
constexpr ld eps = 1e-10;
constexpr ld pi = 3.1415926535897932;
template<class T>inline bool chmax(T& a, const T& b) { if (a < b) { a = b; return true; }return false; }
template<class T>inline bool chmin(T& a, const T& b) { if (a > b) { a = b; return true; }return false; }
inline void init() { cin.tie(nullptr); cout.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(15); }
template<class T>inline istream& operator>>(istream& is, vector<T>& v) { for (auto& a : v)is >> a; return is; }
template<class T, class U>inline istream& operator>>(istream& is, pair<T, U>& p) { is >> p.first >> p.second; return is; }
template<class T>inline vector<T> vec(size_t a) { return vector<T>(a); }
template<class T>inline vector<T> defvec(T def, size_t a) { return vector<T>(a, def); }
template<class T, class... Ts>inline auto vec(size_t a, Ts... ts) { return vector<decltype(vec<T>(ts...))>(a, vec<T>(ts...)); }
template<class T, class... Ts>inline auto defvec(T def, size_t a, Ts... ts) { return vector<decltype(defvec<T>(def, ts...))>(a, defvec<T>(def, ts...)); }
template<class T>inline void print(const T& a) { cout << a << "\n"; }
template<class T, class... Ts>inline void print(const T& a, const Ts&... ts) { cout << a << " "; print(ts...); }
template<class T>inline void print(const vector<T>& v) { for (int i = 0; i < v.size(); ++i)cout << v[i] << (i == v.size() - 1 ? "\n" : " "); }
template<class T>inline void print(const vector<vector<T>>& v) { for (auto& a : v)print(a); }
inline string reversed(const string& s) { string t = s; reverse(all(t)); return t; }
template<class T>inline T sum(const vector<T>& a, int l, int r) { return a[r] - (l == 0 ? 0 : a[l - 1]); }
template<class T>inline void END(T s) { print(s); exit(0); }
void END() { exit(0); }

int m, n;
int parse(string s) {
    if (s == "H")return m + n;
    if (s == "D")return m + n + 1;
    return stoi(s.substr(1)) + (s[0] == 'C' ? 0 : m) - 1;
}

int main() {
    init();

    for (int k, d; cin >> m >> n >> k >> d, m;) {
        int v = m + n + 2;
        VI c(m); cin >> c;
        vector<vector<pair<int, int>>> g(v);
        FOR(i, 0, d) {
            string s, t; int e; cin >> s >> t >> e;
            int a = parse(s), b = parse(t);
            e *= k;
            g[a].emplace_back(b, e);
            g[b].emplace_back(a, e);
        }

        int start = v - 2, goal = v - 1;
        auto dp = defvec<int>(INF, 1 << m, v);
        dp[0][start] = 0;
        FOR(_, 0, v)FOR(bit, 0, 1 << m)FOR(cur, 0, v) {
            if (dp[bit][cur] == INF)continue;
            for (auto [to, cost] : g[cur]) {
                if (to < m) {
                    if (!(bit & (1 << to)))chmin(dp[bit | (1 << to)][to], dp[bit][cur] + cost - c[to]);
                }
                else chmin(dp[bit][to], dp[bit][cur] + cost);
            }
        }

        int ans = INF;
        FOR(i, 0, 1 << m)chmin(ans, dp[i][goal]);
        print(ans);
    }
    

    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 3548
final_rank: 20

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
//using namespace atcoder;
const double pi = 3.141592653589793238462643383279;
using namespace std;
//typedef
//------------------------------------------
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef pair<long long, long long> PLL;
typedef pair<int, PII> TIII;
typedef long long LL;
typedef unsigned long long ULL;
typedef vector<LL> VLL;
typedef vector<VLL> VVLL;

//container util
//------------------------------------------
#define ALL(a) (a).begin(), (a).endf()
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define MP make_pair
#define SZ(a) int((a).size())
#define SQ(a) ((a) * (a))
#define EACH(i, c) for (typeof((c).begin()) i = (c).begin(); i != (c).endf(); ++i)
#define EXIST(s, e) ((s).find(e) != (s).endf())
#define SORT(c) sort((c).begin(), (c).endf())

//repetition
//------------------------------------------
#define FOR(i, s, n) for (int i = s; i < (int)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define MOD 1000000007

#define rep(i, a, b) for (int i = a; i < (b); ++i)
#define trav(a, x) for (auto &a : x)
#define all(x) x.begin(), x.end()
#define sz(x) (int)(x).size()

typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
const double EPS = 1e-4, PI = acos(-1);
//ここから編集    
typedef string::const_iterator State;
int dist[210][(1<<6)];
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(15);

    int m, n, k, d;
    while(cin >> m >> n >> k >> d, m&&n&&k&&d){
        vector<int> c(m);
        REP(i,m) cin >> c[i];
        map<string, int> mp;
        mp["H"] = 0;
        mp["D"] = 1;
        int cnt = 2;
        for(int i=1; i<=n; i++){
            string s = "L";
            s += to_string(i);
            mp[s] = cnt++;
        }
        for(int i=1; i<=m; i++){
            string s = "C";
            s += to_string(i);
            mp[s] = cnt++;
        }

        vector<vector<pair<int, int>>> g(mp.size());
        REP(i,d){
            string s, t;
            cin >> s >> t;
            int c; cin >> c;
            g[mp[s]].push_back({mp[t], c});
            g[mp[t]].push_back({mp[s], c});
        }

        REP(i,210) REP(j,1<<6) dist[i][j] = INT_MAX;
        dist[0][0] = 0;

        priority_queue<pair<int, pair<int, int>>, vector<pair<int, pair<int, int>>>, greater<pair<int, pair<int, int>>>> pq;
        pq.push(make_pair(0, make_pair(0, 0)));

        while(pq.size()){
            auto p = pq.top();
            pq.pop();

            if(dist[p.second.first][p.second.second] < p.first) continue;
            int v = p.second.first;
            int mask = p.second.second;
            
            for(auto e: g[v]){
                int u = e.first;
                if(u>=n+2){
                    int tmp = u-(n+2);
                    if(mask >> tmp&1) continue;

                    if(dist[u][mask | (1<<tmp)] > dist[v][mask] + k*e.second - c[tmp]){
                        dist[u][mask | (1<<tmp)] = dist[v][mask] + k*e.second - c[tmp];
                        pq.push(make_pair(dist[u][mask | (1<<tmp)], make_pair(u, mask|(1<<tmp))));
                    }
                }else{
                    if(dist[u][mask] > dist[v][mask] + k*e.second){
                        dist[u][mask] = dist[v][mask] + k*e.second;
                        pq.push(make_pair(dist[u][mask], make_pair(u, mask)));
                    }
                }
            }
        }
        int ans = INT_MAX;
        for(int i=0; i<(1<<m); i++){
            ans = min(ans, dist[1][i]);
        }
        cout << ans << endl;
    }

    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3336
final_rank: 13

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
#include <queue>
using namespace std;
const int inf = 1e9;

int stoidx(string &s, int n, int m){
    if(s[0] == 'C') return stoi(s.substr(1, (int)s.length()-1)) -1;
    if(s[0] == 'L') return stoi(s.substr(1, (int)s.length()-1)) -1 +m;
    if(s == "H") return m+n;
    return m+n+1;
}

int main(){
    while(1){
        int m,n,k,d;
        cin >> m >> n >> k >> d;
        if(n == 0) break;

        vector<int> cal(m);
        for(int i=0; i<m; i++){
            cin >> cal[i];
        }
        vector<vector<pair<int,int>>> g(n+m+2);
        for(int i=0; i<d; i++){
            string s,t;
            int e;
            cin >> s >> t >> e;
            int si=stoidx(s, n, m);
            int ti=stoidx(t, n, m);
            e *= k;
            g[si].emplace_back(ti, e);
            g[ti].emplace_back(si, e);
        }

        priority_queue<pair<int, pair<int,int>>> wait;
        wait.push({0, {n+m, 0}});
        vector<vector<int>> dp(n+m+2, vector<int>(1<<m, inf));
        dp[n+m][0] = 0;
        while(!wait.empty()){
            int c = -wait.top().first;
            int p = wait.top().second.first;
            int s = wait.top().second.second;
            wait.pop();
            if(c > dp[p][s]) continue;
            for(auto next: g[p]){
                int np = next.first;
                int nc = c +next.second;
                int ns = s;
                if(np < m){
                    nc -= cal[np];
                    ns |= 1<<np;
                    if(ns == s) continue;
                }
                if(nc < dp[np][ns]){
                    dp[np][ns] = nc;
                    wait.push({-nc, {np, ns}});
                }
            }
        }
        cout << *min_element(dp[n+m+1].begin(), dp[n+m+1].end()) << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3344
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<int, int>;

using T = tuple<int, int, int>;
const int INF = 1001001001;

struct edge { int to, cost; };

int m, n, k, d;
int c[11];
vector<edge> g[111];
int dp[111][1 << 6];

int f(string s) {
    if (s == "H") return 0;
    if (s == "D") return n + m + 1;
    if (s[0] == 'C') return (s[1] - '0') + n;
    if (s[0] == 'L') {
        string x = s.substr(1, s.size() - 1);
        return stoi(x);
    }
}

void dijkstra(int s) {
    priority_queue<T, vector<T>, greater<T>> que;
    for (int i = 0; i < 111; i++) {
        for (int bit = 0; bit < (1 << 6); bit++) {
            dp[i][bit] = INF;
        }
    }
    dp[s][(1 << m) - 1] = 0;
    que.push(T(0, s, (1 << m) - 1));
    while (que.size()) {
        T t = que.top(); que.pop();
        int v = get<1>(t);
        int bit = get<2>(t);
        for (auto e : g[v]) {
            int u = -1;
            bool flag = true;
            for (int i = n + 1; i <= n + m; i++) {
                if (e.to == i) {
                    if (bit >> (i - n - 1) & 1) u = i - n - 1;
                    else {
                        flag = false;
                        break;
                    }
                }
            }
            if (!flag) continue;
            if (u == -1) {
                if (dp[e.to][bit] > dp[v][bit] + e.cost) {
                    dp[e.to][bit] = dp[v][bit] + e.cost;
                    que.push(T(dp[e.to][bit], e.to, bit));
                }
            } else {
                if (dp[e.to][bit ^ (1 << u)] > dp[v][bit] + e.cost - c[u]) {
                    dp[e.to][bit ^ (1 << u)] = dp[v][bit] + e.cost - c[u];
                    que.push(T(dp[e.to][bit ^ (1 << u)], e.to, bit ^ (1 << u)));
                }
            }

        }
    }
}

int main() {
    while (cin >> m >> n >> k >> d && (m != 0 || n != 0 || k != 0 || d != 0)) {
        vector<edge> vec[111];
        swap(g, vec);
        for (int i = 0; i < m; i++) cin >> c[i];
        for (int i = 0; i < d; i++) {
            string s, t;
            int e;
            cin >> s >> t >> e;
            g[f(s)].push_back(edge{ f(t), e * k });
            g[f(t)].push_back(edge{ f(s), e * k });
        }
        dijkstra(f("H"));
        int ans = INF;
        for (int bit = 0; bit < (1 << m); bit++) {
            ans = min(ans, dp[f("D")][bit]);
        }
        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 50
memory_kb: 3372
final_rank: 19

code_snippet: #include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <numeric>
#include <bitset>
#include <cmath>

static const int MOD = 1000000007;
using ll = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using namespace std;

template<class T> constexpr T INF = ::numeric_limits<T>::max()/32*15+208;


bool solve(){
    int m, n, k, d;
    cin >> m >> n >> k >> d;
    if(!m) return 0;
    map<string, int> a;
    a["H"] = 0;
    for (int i = 0; i < m; ++i) a[string("C")+to_string(i+1)] = i+1;
    for (int i = 0; i < n; ++i) a[string("L")+to_string(i+1)] = i+m+1;
    a["D"] = n+m+1;
    vector<int> C(m);
    for (auto &&j : C) scanf("%d", &j);
    vector<vector<pair<int, int>>> G(n+m+2);
    for (int i = 0; i < d; ++i) {
        string S, T; int x;
        cin >> S >> T >> x;
        int s = a[S], t = a[T];
        G[s].emplace_back(t, x*k);
        G[t].emplace_back(s, x*k);
    }
    vector<int> dp((n+m+2) << m, INF<int>);
    priority_queue<pair<int, int>,vector<pair<int, int>>,greater<>> Q;
    dp[0] = 0;
    Q.emplace(0, 0);
    int mask = (1 << m)-1;
    while(!Q.empty()){
        int cost; int i;
        tie(cost, i) = Q.top(); Q.pop();
        int down = i & mask, up = i >> m;
        if(dp[i] < cost) continue;
        for (auto &&e : G[up]) {
            auto cost2 = cost + e.second;
            if(1 <= e.first && e.first <= m){
                if((1 << (e.first-1)) & i) continue;;
                int to = down | (1 << (e.first-1)) | (e.first << m);
                if(dp[to] <= cost2) continue;
                dp[to] = cost2;
                Q.emplace(dp[to], to);
            }else {
                int to = down | (e.first << m);
                if(dp[to] <= cost2) continue;
                dp[to] = cost2;
                Q.emplace(dp[to], to);
            }
        }
    }
    int ans = INF<int>;
    for (int i = 0; i < (1 << m); ++i) {
        int val = dp[(n+m+1) << m | i];
        for (int j = 0; j < m; ++j) {
            if(i & (1 << j)){
                val -= C[j];
            }
        }
        ans = min(ans, val);
    }
    cout << ans << "\n";
    return 1;
}

int main() {
    while(solve());
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3360
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long int;
using P = pair<int, int>;
using P3 = pair<int,P>;
using PP = pair<P, P>;
constexpr int INF = 1<<30;
constexpr ll MOD = ll(1e9)+7;
constexpr int di[] = {0,1,0,-1};
constexpr int dj[] = {1,0,-1,0};

bool solve(){
    int N, M, K, E, V;
    cin >> M >> N >> K >> E;
    if(M == 0) return false;
    V = N+M+2;
    vector<vector<P> > g(V);
    vector<int> C(M);
    for(int i=0;i<M;i++){
        cin >> C[i];
    }
    for(int i=0;i<E;i++){
        string s[2];
        int si[2], d;
        cin >> s[0] >> s[1] >> d;
        for(int j=0;j<2;j++){
            if(s[j]=="H") si[j] = 0;
            if(s[j]=="D") si[j] = N+1;
            if(s[j][0]=='L') si[j] = stoi(s[j].substr(1,int(s[j].size())-1));
            if(s[j][0]=='C') si[j] = stoi(s[j].substr(1,int(s[j].size())-1))+N+1;
        }
        g[si[0]].push_back(P(si[1], d));
        g[si[1]].push_back(P(si[0], d));
    }
    vector<vector<int> > dist(1<<M, vector<int>(V, INF));
    dist[0][0] = 0;
    for(int S=0;S<1<<M;S++){
        priority_queue<P,vector<P>,greater<P> > que;
        for(int i=0;i<V;i++){
            que.push(P(dist[S][i],i));
        }
        while(!que.empty()){
            P p = que.top();
            que.pop();
            int v = p.second;
            if(dist[S][v] < p.first) continue;
            for(auto e : g[v]){
                int u = e.first, d = e.second;
                if(u < N+2){
                    if(dist[S][u] > dist[S][v] + d*K){
                        dist[S][u] = dist[S][v] + d*K;
                        que.push(P(dist[S][u], u));
                    }
                }else{
                    int idx = u-(N+2);
                    if((S>>idx)&1) continue;
                    int T = S|(1<<idx);
                    if(dist[T][u] > dist[S][v] + d*K - C[idx]){
                        dist[T][u] = dist[S][v] + d*K - C[idx];
                    }
                }
            }
        }
    }
    int ans = INF;
    for(int S=0;S<1<<M;S++){
        ans = min(ans, dist[S][N+1]);
    }
    cout << ans << endl;
    return true;
}

int main(){
    while(solve());
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3220
final_rank: 10

code_snippet: #include <iostream>
#include <vector>
#include <array>
#include <list>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <tuple>
#include <memory>
#include <cmath>
#include <algorithm>
#include <functional>
#include <iomanip>
#include <numeric>
#include <climits>
#include <cfloat>
#include <cassert>
#include <random>
int factorial(int n) {
	return n == 0 ? 1 : n * factorial(n - 1);
}
int main() {
	while (true) {
		int m, n, k, d; std::cin >> m >> n >> k >> d; if (m == 0 && n == 0) break;
		std::vector<int> calories(m); for (auto& c : calories) std::cin >> c;
		std::vector<std::vector<int>> distances(m + n + 2, std::vector<int>(m + n + 2, INT_MAX));
		for (auto i = 0; i < d; ++i) {
			std::string s, t; int e; std::cin >> s >> t >> e;
			int from = -1, to = -1;
			switch (s.front()) {
			case 'H': from = n + m; break;
			case 'D': from = n + m + 1; break;
			case 'C': from = std::stoi(s.substr(1)) - 1; break;
			case 'L': from = std::stoi(s.substr(1)) + m - 1; break;
			default: break;
			}
			switch (t.front()) {
			case 'H': to = n + m; break;
			case 'D': to = n + m + 1; break;
			case 'C': to = std::stoi(t.substr(1)) - 1; break;
			case 'L': to = std::stoi(t.substr(1)) + m - 1; break;
			default: break;
			}
			distances[from][to] = distances[to][from] = std::min(distances[from][to], e * k);
		}
		for (auto i = 0; i < distances.size(); ++i) distances[i][i] = 0;
		for (auto k = m; k < distances.size(); ++k) {
			for (auto i = 0; i < distances.size(); ++i) if (distances[i][k] != INT_MAX) {
				for (auto j = 0; j < distances.size(); ++j) if (distances[k][j] != INT_MAX) {
					distances[i][j] = std::min(distances[i][j], distances[i][k] + distances[k][j]);
				}
			}
		}
		int min_calory = distances[n + m][n + m + 1];
		std::vector<int> cake_shops(m); std::iota(cake_shops.begin(), cake_shops.end(), 0);
		for (auto _i = factorial(m); _i > 0; --_i) {
			int prev = n + m;
			int distance = 0;
			for (auto i = 0; i < m; ++i) if (distances[prev][cake_shops[i]] != INT_MAX) {
				distance += distances[prev][cake_shops[i]] - calories[cake_shops[i]];
				prev = cake_shops[i];
				if (distances[prev][n + m + 1] != INT_MAX) min_calory = std::min(min_calory, distance + distances[prev][n + m + 1]);
			}
			std::next_permutation(cake_shops.begin(), cake_shops.end());
		}
		std::cout << min_calory << std::endl;
	}
}
accuracy: 1
time_ms: 30
memory_kb: 3112
final_rank: 2

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

const int INF = 1<<28;
const int START = 108;
const int GOAL = 109;

int enc(string s){
    if(s == "H")        return START;
    else if(s == "D")   return GOAL;
    char c = s[0];
    int x = stoi(s.substr(1));
    return (c == 'C' ? 0 : 6) + x-1;
}

int main(){
    int m, n, k, d;
    while(cin >> m >> n >> k >> d, m+n+k+d){
        vector<pair<int,int>> vp[110];
        vector<int> cake(m);
        for(int i = 0; i < m; i++)  cin >> cake[i];
        while(d-- > 0){
            string a, b;
            int c;
            cin >> a >> b >> c;
            int from = enc(a), to = enc(b);
            c *= k;
            vp[from].push_back({to, c});
            vp[to].push_back({from, c});
        }
        vector<vector<int>> dp(110, vector<int>(1<<m, INF));
        dp[START][0] = 0;

        for(int loop = 0; loop < 110*64; loop++){
            bool update = false;
            for(int pos = 0; pos < 110; pos++){
                for(pair<int,int> p : vp[pos]){
                    for(int bit = 0; bit < 1<<m; bit++){
                        if(dp[pos][bit] == INF) continue;
                        int next = p.first, ncost = dp[pos][bit]+p.second;
                        if(next < m){
                            if((bit>>next&1)==0 && ncost-cake[next] < dp[next][bit^(1<<next)]){
                                dp[next][bit^(1<<next)] = ncost-cake[next];
                                update = true;
                            }
                            continue;
                        }
                        if(ncost < dp[next][bit]){
                            dp[next][bit] = ncost;
                            update = true;
                        }
                    }
                }
            }
            if(!update) break;
        }

        int ans = 1<<30;
        for(int i = 0; i < 1<<m; i++){
            ans = min(ans, dp[GOAL][i]);
        }
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3128
final_rank: 3

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
#include<cstring>
#include<queue>
using namespace std;
int m,n,k,d;
int f(string s)
{
	if(s=="H")return 0;
	else if(s=="D")return m+n+1;
	else if(s[0]=='C')return s[1]-'0';
	else return stoi(s.substr(1))+m;
}
main()
{
	while(cin>>m>>n>>k>>d,d)
	{
		int c[6];for(int i=0;i<m;i++)cin>>c[i];
		vector<vector<pair<int,int> > >G(m+n+2);
		for(int i=0;i<d;i++)
		{
			string ss,tt;int e;cin>>ss>>tt>>e;
			int s=f(ss),t=f(tt);
			G[s].push_back(make_pair(t,e*k));
			G[t].push_back(make_pair(s,e*k));
		}
		vector<vector<int> >d(m+n+2,vector<int>(1<<m,1e9));
		priority_queue<pair<int,pair<int,int> > >P;
		d[0][0]=0;
		P.push(make_pair(0,make_pair(0,0)));
		while(!P.empty())
		{
			int D=-P.top().first,u=P.top().second.first,L=P.top().second.second;
			P.pop();
			if(d[u][L]<D)continue;
			for(int i=0;i<G[u].size();i++)
			{
				int v=G[u][i].first,cost=G[u][i].second;
				int next=L;
				if(v>=1&&v<=m)
				{
					if(L&1<<v-1)continue;
					next|=1<<v-1;
				}
				if(d[v][next]>D+cost)
				{
					d[v][next]=D+cost;
					P.push(make_pair(-d[v][next],make_pair(v,next)));
				}
			}
		}
		vector<int>sc(1<<m,0);
		for(int i=0;i<1<<m;i++)
		{
			for(int j=0;j<m;j++)if(i&1<<j)sc[i]+=c[j];
		}
		int ans=1e9;
		for(int i=0;i<1<<m;i++)
		{
			ans=min(ans,d[m+n+1][i]-sc[i]);
		}
		cout<<ans<<endl;
	}
}
accuracy: 1
time_ms: 40
memory_kb: 3096
final_rank: 6

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
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 Data{
	Data(int arg_to,int arg_cost){
		to = arg_to;
		cost = arg_cost;
	}
	int to,cost;
};

int M,N,K,D;
int POW[7] = {1,2,4,8,16,32,64};

int getNUM(char buf[5]){

	int ret = 0;
	for(int i = 1; buf[i] != '\0'; i++){
		ret = 10*ret + (buf[i]-'0');
	}
	ret--;

	switch(buf[0]){
	case 'L':
		return ret+M+2;
	case 'C':
		return ret+2;
	case 'H':
		return 0;
	case 'D':
		return 1;
	}

	return -1; //must not reach here
}

void func(){

	int cake_value[M],min_Cost[M+N+2][POW[M]];

	for(int i = 0; i < M+N+2; i++){
		for(int k = 0; k < POW[M]; k++)min_Cost[i][k] = BIG_NUM;
	}

	vector<Data> V[M+N+2];

	for(int i = 0; i < M; i++)scanf("%d",&cake_value[i]);

	char left[5],right[5];
	int cost,left_num,right_num;

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

		left_num = getNUM(left);
		right_num = getNUM(right);

		if(left[0] != 'C' && right[0] != 'C'){
			V[left_num].push_back(Data(right_num,K*cost));
			V[right_num].push_back(Data(left_num,K*cost));
		}else if(left[0] == 'C' && right[0] != 'C'){
			V[left_num].push_back(Data(right_num,K*cost));
			V[right_num].push_back(Data(left_num,K*cost-cake_value[left_num-2]));
		}else if(left[0] != 'C' && right[0] == 'C'){
			V[left_num].push_back(Data(right_num,K*cost-cake_value[right_num-2]));
			V[right_num].push_back(Data(left_num,K*cost));
		}else{
			V[left_num].push_back(Data(right_num,K*cost-cake_value[right_num-2]));
			V[right_num].push_back(Data(left_num,K*cost-cake_value[left_num-2]));
		}
	}

	min_Cost[0][0] = 0;

	bool updated;
	int next_state;

	for(int loop = 0; loop < N+M+2; loop++){
		updated = false;

		for(int from = 0; from < N+M+2; from++){
			for(int i = 0; i < V[from].size();i++){
				for(int state = 0; state < POW[M];state++){
					if(min_Cost[from][state] != BIG_NUM){
						if(V[from][i].to >= 2 && V[from][i].to <= 2+M-1){
							if(state & (1 << (V[from][i].to-2))){
								//Do nothing
							}else{
								next_state = state + POW[V[from][i].to-2];
								if(min_Cost[V[from][i].to][next_state] > min_Cost[from][state] + V[from][i].cost){
									min_Cost[V[from][i].to][next_state] = min_Cost[from][state] + V[from][i].cost;
									updated = true;
								}
							}

						}else{
							if(min_Cost[V[from][i].to][state] > min_Cost[from][state] + V[from][i].cost){
								min_Cost[V[from][i].to][state] = min_Cost[from][state] + V[from][i].cost;
								updated = true;
							}
						}
					}

				}
			}
		}

		if(!updated)break;
	}

	int ans = BIG_NUM;
	for(int i = 0; i < POW[M];i++)ans = min(ans,min_Cost[1][i]);

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

int main(){

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

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 2632
final_rank: 1

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<functional>
#include<string>
#include<stdlib.h>

using namespace std;
typedef pair<int, int> Pi;
typedef pair<int, Pi> Ti;
const int INF = 10000000;

int m, n, k, d;
int cake_cal[6];
vector<vector<Pi>> edge;
//home := 0 cake_shop := 1 ~ m landmark := m+1 ~ m+n city_holl := m+n+1

int djk(int s, int g) {
	int d[128][1 << 6];//d[i][j] i:= Node j:= Visited node's memo by bits 
	for (int i = 0; i < m + n + 2; i++)for (int j = 0; j < (1 << 6); j++)d[i][j] = INF;
	d[s][0] = 0;
	priority_queue<Ti, vector<Ti>, greater<Ti>> pq;//cost Node bit
	pq.push(make_pair(0, make_pair(s, 0)));
	while (pq.size()) {
		Ti tmp = pq.top(); pq.pop();
		int N = tmp.second.first, bit = tmp.second.second;
		if (d[N][bit] < tmp.first)continue;
		for (int i = 0; i < edge[N].size(); i++) {
			int to = edge[N][i].first, cost = edge[N][i].second;
			if (to >= 1 && to <= m) {
				//??±???????±?????????°
				if ((bit >> (to - 1)) & 1)continue;//?????§????????£??????????????°
				if (d[to][bit | 1 << (to - 1)] > d[N][bit] + cost - cake_cal[to - 1]) {
					//??????????????¨???????????????????????§??????????????§???????????????
					d[to][bit | 1 << (to - 1)] = d[N][bit] + cost - cake_cal[to - 1];
					pq.push(make_pair(d[to][bit | 1 << (to - 1)],
						make_pair(to, bit | 1 << (to - 1))
					));
				}
			}
			else {
				//??????????????????????????°
				if (d[to][bit] > d[N][bit] + cost) {
					d[to][bit] = d[N][bit] + cost;
					pq.push(make_pair(d[to][bit], make_pair(to, bit)));
				}
			}
		}
	}
	int res = INF;
	for (int i = 0; i < (1 << 6); i++)res = min(res, d[g][i]);
	return res;
}

int conv(const char *s1){
	if (s1[0] == 'H') return (0);
	if (s1[0] == 'D') return (m + n + 1);
	if (s1[0] == 'C') return (atoi(s1 + 1));
	return (atoi(s1 + 1) + m);
}


int main() {
	while (cin >> m >> n >> k >> d, m + m + k + d) {
		for (int i = 0; i < m; i++)cin >> cake_cal[i];
		edge.resize(2 + m + n);
		//??±?????????????????????????????????????????±???????±????????????????
		for (int i = 0; i < d; i++) {
			string s1, s2; int cost;
			cin >> s1 >> s2 >> cost;
			edge[conv(s1.c_str())].push_back(make_pair(conv(s2.c_str()), cost * k));
			edge[conv(s2.c_str())].push_back(make_pair(conv(s1.c_str()), cost * k));
		}
		cout << djk(0, m + n + 1) << endl;
		edge.clear();
	}
	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3332
final_rank: 12

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define REP(i, a, b) for ( int i = a; i < b; i++ )
#define rep(i, n) REP(i, 0, n)
#define INFTY (1<<21)
int m, n, k, d, C[7], G[110][110], N, D[110][64];
int getID(string str) {if (str == "H")return 0;
	if (str == "D")return N - 1;
	string num = str.substr(1, str.size() - 1);
	if (str[0] == 'C')return atoi(num.c_str());
	return atoi(num.c_str()) + m;
}
bool isC(int x) {
	return 1 <= x && x <= m;}
int bellman() {
	rep(i, N)
		rep(j, (1<<m))
			D[i][j] = INFTY;
	D[0][0] = 0;
	rep(o, N*(1<<m))
	{
		bool change = false;
		rep(u, N)
			rep(v, N)
			{
				if (u == v || G[u][v] == INFTY)
					continue;
				rep(b, (1<<m))
				{
					if (isC(v) && (b & (1 << (v - 1))) != 0)
						continue;
					if (isC(v)) {
						if (D[u][b] + G[u][v] - C[v]
								< D[v][b | (1 << (v - 1))]) {
							D[v][b | (1 << (v - 1))] = D[u][b] + G[u][v] - C[v];
							change = true;
						}
					} else {
						if (D[u][b] + G[u][v] < D[v][b]) {
							D[v][b] = D[u][b] + G[u][v];
							change = true;
						}
					}
				}
			}
		if (!change)
			break;
	}
	int minv = INFTY;
	rep(i, (1<<m))
		minv = min(minv, D[N - 1][i]);
	return minv;
}
int main() {
	string source, target;
	int cost;
	while (cin >> m >> n >> k >> d && m) {
		N = 2 + n + m;
		REP(i, 1, m+1)
			cin >> C[i];
		rep(i, N)
			rep(j, N)
				G[i][j] = INFTY;
		rep(i, d)
		{
			cin >> source >> target >> cost;
			int s = getID(source);
			int t = getID(target);
			G[t][s] = G[s][t] = min(G[s][t], cost * k);
		}
		cout << bellman() << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3136
final_rank: 4

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

using namespace std;

#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
#define fi first
#define se second

template<typename A, typename B> inline bool chmax(A &a, B b) { if (a<b) { a=b; return 1; } return 0; }
template<typename A, typename B> inline bool chmin(A &a, B b) { if (a>b) { a=b; return 1; } return 0; }

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<int, pii> pip;
const ll INF = 1ll<<29;
const ll MOD = 1000000007;
const double EPS  = 1e-9;

int dp[1<<6][110];
int m, n, k, d;
vector<pii> g[110]; // [0,m):??±???????±?, [m,m+n):??????????????????, m+n:??????, m+n+1:?????????
int c[6];

int input() {
	char ch;
	int num;
	scanf(" %c", &ch);
	if (ch == 'H') return m + n;
	if (ch == 'D') return m + n + 1;
	scanf("%d", &num);
	
	int res = num - 1;
	if (ch == 'L') res += m;
	return res;
}

int main() {
	while (cin >> m >> n >> k >> d, m || n || k || d) {
		REP(i, m) scanf("%d", c + i);
		
		REP(i, m + n + 2) g[i].clear();
		
		REP(i, d) {
			int u = input();
			int v = input();
			int e; scanf("%d", &e);
			
			g[u].push_back(pii(v, e * k));
			g[v].push_back(pii(u, e * k));
		}
		
		
		fill(dp[0], dp[1<<m], INF);
		priority_queue<pip, vector<pip>, greater<pip> > pq;
		pq.push(pip(0, pii(0, m + n)));
		dp[0][m + n] = 0;
		
		while (!pq.empty()) {
			pip now = pq.top(); pq.pop();
			
			int s = now.se.fi;
			int u = now.se.se;
			
			REP(i, g[u].size()) {
				int v = g[u][i].fi;
				int nc = now.fi + g[u][i].se;
				
				if (v < m && s >> v & 1) continue;
				int ns = s;
				if (v < m) ns |= 1<<v;
				
				if (!chmin(dp[ns][v], nc)) continue;
				pq.push(pip(nc, pii(ns, v)));
			}
		}
		
		int ans = INF;
		REP(i, 1 << m) if (dp[i][n + m + 1] != INF) {
			int sum = 0;
			REP(j, m) if (i >> j & 1) sum += c[j];
			chmin(ans, dp[i][n + m + 1] - sum);
		}
		
		cout << ans << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3180
final_rank: 9