3641: 货车运输
Time Limit: 20 Sec Memory Limit: 256 MBSec Special JudgeSubmit: 64 Solved: 27
[Submit][Status][Discuss]
Description
saffah所在的国家一共有N个城市,通过N条双向道路连接,使得城市之间两两可以到达。第i条道路连接了A[i]与B[i],其长度为L[i] km。
这些道路分为M个等级。第i条道路的等级为X[i]。在第j级道路上行驶,你的限速是V[j] km/h,并且每行驶1小时会收取W[j]元的费用。根据道路分级的意义,V[j]与W[j]都随着j单调变化,即对于1 ≤ j < M,满足V[j] > V[j+1], W[j] > W[j+1]。
现在有Q辆货车需要运送货物。第k辆货车要从S[k]前往T[k],并且其最大速度为U[k] km/h。你需要对每辆货车求出其最小运送花费。
Input
第一行三个整数N, M, Q。
接下来N行,每行四个整数A[i], B[i], L[i], X[i],描述了一条道路。
接下来M行,每行两个整数V[j], W[j],描述了一个道路等级的限速和费用。
接下来Q行,每行三个整数S[k], T[k], U[k],描述了一辆货车。
Output
输出Q行,即每辆货车的最小运送花费。
你可以输出任意多位的实数,只要与标准答案的相对或绝对误差不超过0.0001就算正确。
Sample Input
4 2 2
1 2 50 1
2 3 50 1
1 3 50 2
3 4 50 1
100 20
10 10
1 4 100
1 4 10
1 2 50 1
2 3 50 1
1 3 50 2
3 4 50 1
100 20
10 10
1 4 100
1 4 10
Sample Output
30
150
150
HINT
对于所有的数据,1 ≤ N,M,Q ≤ 100,000, 1 ≤ A[i],B[i],S[k],T[k] ≤ N, 1 ≤ X[i] ≤ M, 1 ≤ L[i],V[j],W[j],U[k] ≤ 500,000。
样例解释:
第一辆货车应该沿1→2→3→4行驶,共在1级道路上行驶1.5小时,收费30元。
第二辆货车应该沿1→3→4行驶,在2级道路上行驶5小时,在1级道路上行驶5小时,收费150元。
出题人真是调皮,上来就给8个数组。。
傻逼代码题。。调了蛮久(主要是数据。。找了半天。。CH各种坑啊。。)。。最后发现
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
rep(i, 1, cCnt) { dep[cir[i]] = 1; }
写成:
rep(i, 1, cCnt) { dep[i] = 1; }
23333
rk3的代码。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 == ' ' || ret == ' ' || 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 ", 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 ", top); 163 } 164 if (u == 14257) { 165 printf("14257 %d ", 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 ", (double)ans); 276 } 277 278 return 0; 279 }