1 /**************************************************************
2 Problem: 1003
3 User: Asm.Def
4 Language: C++
5 Result: Accepted
6 Time:24 ms
7 Memory:1376 kb
8 ****************************************************************/
9
10 #include <iostream>
11 #include <cctype>
12 #include <cstdio>
13 #include <vector>
14 #include <algorithm>
15 #include <cmath>
16 #include <queue>
17 using namespace std;
18 inline void getd(int &x){
19 char c = getchar();
20 bool minus = 0;
21 while(!isdigit(c) && c != ‘-‘)c = getchar();
22 if(c == ‘-‘)minus = 1, c = getchar();
23 x = c - ‘0‘;
24 while(isdigit(c = getchar()))x = x * 10 + c - ‘0‘;
25 if(minus)x = -x;
26 }
27 /*======================================================*/
28 const int maxn = 102, maxm = 21, INF = 0x3f3f3f3f;
29
30 struct event{int T, num; } E[2002];
31 inline bool operator < (const event &a, const event &b){
32 return a.T < b.T;
33 }
34
35 int n, m, K, Ecnt = 0;
36 int inval[maxn][maxn] = {0}, cost[maxn][maxn], dp[maxn];
37
38 struct edge{
39 int to, w;
40 edge(int t, int c):to(t), w(c){}
41 };
42 vector<edge> adj[maxm];
43
44 queue<int> Q;
45 bool inQ[maxm] = {0};
46 int dis[maxm] = {0};
47 inline void setinf(){
48 dis[1] = 0;
49 for(int i = 2;i <= m;++i)
50 dis[i] = INF;
51 }
52
53 inline void pushQ(int x){
54 vector<edge>::iterator it;
55 for(int i=1, j=2;i <= m;++i, j <<= 1)
56 if(x & j){
57 if(!inQ[i])Q.push(i), inQ[i] = 1;
58 for(it = adj[i].begin();it != adj[i].end();++it)
59 if(!inQ[it->to])Q.push(it->to), inQ[it->to] = 1;
60 }
61 }
62
63 inline int spfa(int l, int r){
64 vector<edge>::iterator it;
65 int t;
66 while(!Q.empty()){
67 t = Q.front(); Q.pop(); inQ[t] = 0;
68 for(it = adj[t].begin();it != adj[t].end();++it)
69 if((!(inval[l][r] & (1 << it->to))) && dis[it->to] > dis[t] + it->w){
70 dis[it->to] = dis[t] + it->w;
71 if(!inQ[it->to])
72 Q.push(it->to), inQ[it->to] = 1;
73 }
74 }
75 return dis[m];
76 }
77
78 inline void init(){
79 int i, j, e, k, d;
80 getd(n), getd(m), getd(K), getd(e);
81 while(e--){
82 getd(i), getd(j), getd(k);
83 adj[i].push_back(edge(j, k));
84 adj[j].push_back(edge(i, k));
85 }
86 getd(d);
87 while(d--){
88 getd(k), getd(i), getd(j);
89 E[Ecnt].T = i, E[Ecnt].num = k; ++Ecnt;
90 E[Ecnt].T = j+1, E[Ecnt].num = k; ++Ecnt;
91 }
92 sort(E, E + Ecnt);
93 for(j = 0, i = 1;i <= n;++i){
94 inval[i][i] = inval[i-1][i-1];
95 while(j < Ecnt && E[j].T == i){
96 inval[i][i] ^= (1 << E[j].num);
97 ++j;
98 }
99 }
100 for(i = 1;i < n;++i)
101 for(j = i+1;j <= n;++j)
102 inval[i][j] = inval[i][j-1] | inval[j][j];
103 for(i = 1;i <= n;++i){
104 setinf();
105 Q.push(1), inQ[1] = 1;
106 cost[i][n] = spfa(i, n);
107 for(j = n-1;j >= i;--j){
108 if(inval[i][j] == inval[i][j+1]){
109 cost[i][j] = cost[i][j+1];
110 continue;
111 }
112 pushQ(inval[i][j] ^ inval[i][j+1]);
113 if(!inQ[1])Q.push(1), inQ[1] = 1;
114 cost[i][j] = spfa(i, j);
115 }
116 }
117
118 }
119
120 inline void work(){
121 int i, j, c;
122 for(i = 1;i <= n;++i)
123 dp[i] = cost[1][i] == INF ? INF : cost[1][i] * i;
124 for(i = 2;i <= n;++i) for(j = 1;j < i;++j){
125 if(cost[j+1][i] == INF)continue;
126 c = dp[j] + cost[j+1][i] * (i - j) + K;
127 if(c < dp[i])
128 dp[i] = c;
129 }
130 printf("%d\n", dp[n]);
131 }
132
133 int main(){
134 #if defined DEBUG
135 freopen("test", "r", stdin);
136 #else
137 //freopen("bzoj_1002.in", "r", stdin);
138 //freopen("bzoj_1002.out", "w", stdout);
139 #endif
140 init();
141
142 work();
143
144 #if defined DEBUG
145 cout << endl << (double)clock()/CLOCKS_PER_SEC << endl;
146 #endif
147 return 0;
148 }