1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4 #include <iostream>
5 #include <cmath>
6 #include <string>
7 #include <vector>
8 #include <map>
9 #include <set>
10 #include <queue>
11 #include <climits>
12 #include <cstdlib>
13 #include <ctime>
14 using namespace std;
15 namespace my_useful_tools {
16 #define rep(_i, _k, _j) for(int _i = _k; _i <= _j; ++_i)
17 #define reu(_i, _k, _j) for(int _i = _k; _i < _j; ++_i)
18 #define red(_i, _k, _j) for(int _i = _k; _j <= _i; --_i)
19 #define foreach(_i, _s) for(typeof(_s.begin()) _i = _s.begin(); _i != _s.end(); ++_i)
20 #define pb push_back
21 #define mp make_pair
22 #define ipir pair<int, int>
23 #define ivec vector<int>
24 #define clr(t) memset(t, 0, sizeof t)
25 #define pse(t, v) memset(t, v, sizeof t)
26 #define brl puts("")
27 #define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
28 #define file_hza freopen("input.txt", "r", stdin), freopen("output.txt", "w", stdout);
29 #define file_gen(x) freopen(#x".in", "w", stdout);
30 const int INF = 0x3f3f3f3f;
31 typedef long long LL;
32 typedef long double DB;
33 inline void pc(char c) { putchar(c); }
34 template<class T> inline T gcd(T a, T b) { return b == 0 ? a : gcd(b, a % b); }
35 inline char gchar() { char ret = getchar(); for(; ret == ‘\n‘ || ret == ‘\r‘ || ret == ‘ ‘; ret = getchar()); return ret; }
36 template<class T> inline void fr(T&ret) { char c = ‘ ‘; int flag = 1; for(c = getchar(); c != ‘-‘ && !(‘0‘ <= c && c <= ‘9‘); c = getchar());
37 if(c == ‘-‘) flag = -1, ret = 0; else ret = c - ‘0‘; for(c = getchar(); ‘0‘ <= c && c <= ‘9‘; c = getchar()) ret = ret * 10 + c - ‘0‘;
38 ret = ret * flag;
39 }
40 inline int fr() { int x; fr(x); return x; }
41 template<class T> inline void fr(T&a, T&b) { fr(a), fr(b); } template<class T> inline void fr(T&a, T&b, T&c) { fr(a), fr(b), fr(c); }
42 template<class T> inline T fast_pow(T base, T index, T mod = 2147483647, T ret = 1) {
43 for(; index; index >>= 1, base = base * base % mod) if(index & 1) ret = ret * base % mod;
44 return ret;
45 }
46 };
47 using namespace my_useful_tools;
48
49 const int maxn = 1e5 + 100;
50
51
52 int e, h[maxn], to[maxn*2], nxt[maxn*2], dis[maxn*2], rnk[maxn*2];
53 void addEdge(int u, int v, int c, int d) {
54 nxt[e] = h[u], to[e] = v, rnk[e] = c, dis[e] = d, h[u] = e++;
55 nxt[e] = h[v], to[e] = u, rnk[e] = c, dis[e] = d, h[v] = e++;
56 }
57
58 int V[maxn], W[maxn];
59 int n, m, q;
60
61 int fa[maxn], pa[maxn][21], cir[maxn], cCnt, onCir[maxn], dep[maxn], owner[maxn], lnk[maxn];
62
63 void get_cir(int u) {
64 //printf("%d\n", u);
65 for (int i=h[u]; i !=-1; i=nxt[i]) {
66 if (i != fa[u]) {
67 if (dep[to[i]] > 0) {
68 cir[++cCnt] = u;
69 lnk[cCnt] = fa[u];
70 while (u != to[i]) {
71 u = to[fa[u]];
72 cir[++cCnt] = u;
73 lnk[cCnt] = fa[u];
74 }
75 lnk[cCnt] = i;
76 break;
77 }
78 fa[to[i]] = i^1;
79 dep[to[i]] = dep[u]+1;
80 get_cir(to[i]);
81 if (cCnt != 0) break;
82 }
83 }
84 }
85
86 const int maxNode = ((maxn<<2)+maxn*30)*2;
87 #define cn cmt_node
88 #define lc ch[0]
89 #define rc ch[1]
90 struct cmt_node {
91 cn*ch[2];
92 long double a, b;
93 cn() {
94 ch[0] = ch[1] = NULL;
95 a = b = 0.0;
96 }
97 } pool[maxNode], *loc=pool, *root, *trt[maxn], *crt[maxn];
98
99 void build(int l, int r, cn*&rt) {
100 if (rt == NULL)
101 rt = loc++;
102 if (l == r) return ;
103 int mid=(l+r)>>1;
104 build(l, mid, rt->lc);
105 build(mid+1, r, rt->rc);
106 }
107
108 int rk;
109 long double aa, ab;
110 void insert(int l, int r, cn*&rt, cn*pre) {
111 rt = loc++;
112 rt->a = pre->a+aa, rt->b = pre->b+ab;
113 if (l == r) return ;
114 int mid = (l+r)>>1;
115 if (rk <= mid) rt->rc=pre->rc, insert(l, mid, rt->lc, pre->lc);
116 else rt->lc=pre->lc, insert(mid+1, r, rt->rc, pre->rc);
117 }
118 long double queryA(int ql, int qr, int l, int r, cn*ra, cn*rb, cn*f) {
119 if (ql <= l && r <= qr) {
120 return ra->a + rb->a - 2.0*f->a;
121 }
122 int mid = (l+r)>>1;
123 long double ret = 0.0;
124 if (ql <= mid) ret += queryA(ql, qr, l, mid, ra->lc, rb->lc, f->lc);
125 if (mid < qr) ret += queryA(ql, qr, mid+1, r, ra->rc, rb->rc, f->rc);
126 return ret;
127 }
128 long double queryB(int ql, int qr, int l, int r, cn*ra, cn*rb, cn*f) {
129 if (ql <= l && r <= qr) {
130 return ra->b + rb->b - 2.0*f->b;
131 }
132 int mid = (l+r)>>1;
133 long double ret = 0.0;
134 if (ql <= mid) ret += queryB(ql, qr, l, mid, ra->lc, rb->lc, f->lc);
135 if (mid < qr) ret += queryB(ql, qr, mid+1, r, ra->rc, rb->rc, f->rc);
136 return ret;
137 }
138 long double queryA(int ql, int qr, int l, int r, cn*ra, cn*rb) {
139 if (ql <= l && r <= qr) {
140 return rb->a - ra->a;
141 }
142 int mid = (l+r)>>1;
143 long double ret = 0.0;
144 if (ql <= mid) ret += queryA(ql, qr, l, mid, ra->lc, rb->lc);
145 if (mid < qr) ret += queryA(ql, qr, mid+1, r, ra->rc, rb->rc);
146 return ret;
147 }
148 long double queryB(int ql, int qr, int l, int r, cn*ra, cn*rb) {
149 if (ql <= l && r <= qr) {
150 return rb->b - ra->b;
151 }
152 int mid = (l+r)>>1;
153 long double ret = 0.0;
154 if (ql <= mid) ret += queryB(ql, qr, l, mid, ra->lc, rb->lc);
155 if (mid < qr) ret += queryB(ql, qr, mid+1, r, ra->rc, rb->rc);
156 return ret;
157 }
158
159 void dfs(int u, int f, int top) {
160 /*
161 if (u == 93078) {
162 printf("93078 %d\n", top);
163 }
164 if (u == 14257) {
165 printf("14257 %d\n", top);
166 }
167 */
168 owner[u] = top;
169 //pa[u][0] = f;
170 for (int i=h[u]; i!=-1; i=nxt[i])
171 if (to[i] != f && !onCir[to[i]]) {
172 pa[to[i]][0] = u;
173 dep[to[i]] = dep[u]+1;
174 rk = rnk[i];
175 aa = (DB)dis[i]*W[rk];
176 ab = (DB)dis[i]/V[rk]*W[rk];
177 insert(1, m, trt[to[i]], trt[u]);
178 dfs(to[i], u, top);
179 }
180 }
181
182 int lca(int u, int v) {
183 if (dep[u] < dep[v]) swap(u, v);
184 red(i, 20, 0)
185 if (dep[pa[u][i]] >= dep[v])
186 u = pa[u][i];
187 if (u == v) return u;
188 red(i, 20, 0)
189 if (pa[u][i] != pa[v][i])
190 u=pa[u][i], v=pa[v][i];
191 return pa[u][0];
192 }
193
194 vector<int> rV;
195 vector<int>::iterator it;
196 int getRank(int u) {
197 it = upper_bound(rV.begin(), rV.end(), u);
198 if (it == rV.end()) return 1;
199 int v = it-rV.begin();
200 return m-v+1;
201 }
202 long double qMinCost(int s, int t, int u, int r) {
203 if (s == t) return 0;
204 int f = lca(s, t);
205 long double ret = 0.0;
206 if (1 <= r-1) ret += queryA(1, r-1, 1, m, trt[s], trt[t], trt[f])/u;
207 if (r <= m) ret += queryB(r, m, 1, m, trt[s], trt[t], trt[f]);
208 return ret;
209 }
210 long double qMinCost2(int s, int t, int u, int r) {
211 if (t <= s) return 0;
212 long double ret = 0.0;
213 if (1 <= r-1) ret += queryA(1, r-1, 1, m, crt[s], crt[t])/(long double)u;
214 if (r <= m) ret += queryB(r, m, 1, m, crt[s], crt[t]);
215 return ret;
216 }
217
218 int main() {
219 fr(n, m, q);
220 root = NULL;
221 build(1, m, root);
222 trt[0] = crt[0] = root;
223 rep(i, 1, n) trt[i] = NULL;
224 e = 0, pse(h, -1);
225 int a, b, c, d;
226 rep(i, 1, n) {
227 fr(a, b), fr(d, c);
228 addEdge(a, b, c, d);
229 }
230 rep(i, 1, m)
231 fr(V[i], W[i]);
232 pse(fa, -1);
233 dep[1] = 1;
234 get_cir(1);
235 rep(i, 1, cCnt)
236 onCir[cir[i]] = i;
237 dep[0] = 0;
238 crt[0] = root;
239 rep(i, 1, cCnt) {
240 dep[cir[i]] = 1;
241 trt[cir[i]] = root;
242 dfs(cir[i], 0, cir[i]);
243 crt[i] = NULL;
244 int p = (i==1?lnk[cCnt]:lnk[i-1]);
245 rk = rnk[p];
246 aa = (DB)dis[p]*W[rk];
247 ab = (DB)dis[p]*W[rk]/V[rk];
248 insert(1, m, crt[i], crt[i-1]);
249 }
250 rep(j, 1, 20)
251 rep(i, 1, n)
252 pa[i][j] = pa[pa[i][j-1]][j-1];
253
254 rep(i, 1, m)
255 rV.pb(V[i]);
256 reverse(rV.begin(), rV.end());
257 int s, t, u, r;
258 while (q--) {
259 fr(s, t, u);
260 long double ans = 0.0;
261 r = getRank(u);
262 if (owner[s] == owner[t]) {
263 ans = qMinCost(s, t, u, r);
264 } else {
265 if (onCir[owner[t]] < onCir[owner[s]])
266 swap(s, t);
267 ans += qMinCost(s, owner[s], u, r);
268 ans += qMinCost(t, owner[t], u, r);
269 long double x = qMinCost2(onCir[owner[s]], onCir[owner[t]], u, r);
270 long double y = qMinCost2(1, onCir[owner[s]], u, r);
271 long double z = qMinCost2(onCir[owner[t]], cCnt, u, r);
272 long double w = qMinCost2(0, 1, u, r);
273 ans += min(x, y+z+w);
274 }
275 printf("%lf\n", (double)ans);
276 }
277
278 return 0;
279 }