# 3641:货车运输

## 3641: 货车运输

Time Limit: 20 Sec  Memory Limit: 256 MBSec  Special Judge
Submit: 64  Solved: 27
[Submit][Status][Discuss]

## Description

saffah所在的国家一共有N个城市，通过N条双向道路连接，使得城市之间两两可以到达。第i条道路连接了A[i]与B[i]，其长度为L[i] km。

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

30
150

## HINT

    rep(i, 1, cCnt) {
dep[cir[i]] = 1;
}
View Code

    rep(i, 1, cCnt) {
dep[i] = 1;
}

23333

rk3的代码。。

  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);
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 }
View Code

posted @ 2015-04-02 23:21  sbit  阅读(401)  评论(0编辑  收藏