# BZOJ 2125: 最短路

## 2125: 最短路

Time Limit: 1 Sec  Memory Limit: 259 MB
Submit: 756  Solved: 331
[Submit][Status][Discuss]

9 10 2
1 2 1
1 4 1
3 4 1
2 3 1
3 7 1
7 8 2
7 9 2
1 5 3
1 6 4
5 6 1
1 9
5 7

5
6

## Source

[Submit][Status][Discuss]

  1 #include <cstdio>
2 #include <cstring>
3
4 inline int nextChar(void)
5 {
6     static const int siz = 1 << 20;
7
8     static char buf[siz];
9     static char *hd = buf + siz;
10     static char *tl = buf + siz;
11
12     if (hd == tl)
13         fread(hd = buf, 1, siz, stdin);
14
15     return int(*hd++);
16 }
17
18 inline int nextInt(void)
19 {
20     int r = 0, c = nextChar();
21
22     for (; c < 48; c = nextChar());
23     for (; c > 47; c = nextChar())
24         r = r * 10 + c - '0';
25
26     return r;
27 }
28
29 template <class T>
30 inline T min(const T &a, const T &b)
31 {
32     return a < b ? a : b;
33 }
34
35 template <class T>
36 inline T abs(const T &x)
37 {
38     return x < 0 ? -x : x;
39 }
40
41 const int mxn = 500005;
42 const int inf = 0x3f3f3f3f;
43
44 int n, m, q;
45
46 int tot;
47 int hd[mxn];
48 int to[mxn];
49 int vl[mxn];
50 int nt[mxn];
51
52 inline void add(int x, int y, int w)
53 {
54     nt[tot] = hd[x];
55     to[tot] = y;
56     vl[tot] = w;
57     hd[x] = tot++;
58 }
59
60 int dis[mxn];
61 int que[mxn];
62 int vis[mxn];
63
64 inline void spfa(void)
65 {
66     memset(vis,   0, sizeof vis);
67     memset(dis, inf, sizeof dis);
68
69     int lt = 0, rt = 0;
70
71     que[rt++] = 1;
72     vis[1] = 1;
73     dis[1] = 0;
74
75     while (lt != rt)
76     {
77         int u = que[lt++], v;
78
79         if (lt > mxn)lt = 0;
80
81         vis[u] = 0;
82
83         for (int i = hd[u]; ~i; i = nt[i])
84             if (v = to[i], dis[v] > dis[u] + vl[i])
85             {
86                 dis[v] = dis[u] + vl[i];
87
88                 if (!vis[v])
89                 {
90                     vis[que[rt++] = v] = 1;
91
92                     if (rt > mxn)rt = 0;
93                 }
94             }
95     }
96 }
97
98 struct data
99 {
100     int u, v, w;
101
102     inline data(void) {};
103     inline data(int a, int b, int c)
104         : u(a), v(b), w(c) {};
105 }stk[mxn]; int top;
106
107 int tim;
108 int dfn[mxn];
109 int low[mxn];
110
111 int cnt;
112 int cir[mxn];
113 int len[mxn];
114 int bel[mxn];
115 int fat[mxn][25];
116
117 inline void addcir(int u, int v)
118 {
119     ++cnt;
120
121     while (u != stk[top].u && v != stk[top].v)
122     {
123         int x = stk[top].u, y = stk[top].v, w = stk[top].w;
124
125         if (x != u)bel[x] = cnt, fat[x][0] = u;
126         if (y != u)bel[y] = cnt, fat[y][0] = u;
127
128         len[cnt] += w, cir[x] = cir[y] + w;
129
130         --top;
131     }
132
133     {
134         int x = stk[top].u, y = stk[top].v, w = stk[top].w;
135
136         len[cnt] += w, cir[x] = cir[y] + w;
137
138         fat[y][0] = x;
139
140         --top;
141     }
142 }
143
144 void tarjan(int u, int f)
145 {
146     dfn[u] = low[u] = ++tim;
147
148     for (int i = hd[u], v; ~i; i = nt[i])
149         if ((v = to[i]) != f)
150         {
151             if (!dfn[v])
152             {
153                 stk[++top] = data(u, v, vl[i]), tarjan(v, u);
154
155                 if (low[v] < low[u])low[u] = low[v];
156
157                 if (low[v] >= dfn[u])addcir(u, v);
158             }
159             else if (dfn[v] < low[u])
160                 low[u] = dfn[v], stk[++top] = data(u, v, vl[i]);
161         }
162 }
163
164 int dep[mxn];
165
166 void build(int u)
167 {
168     for (int i = hd[u]; ~i; i = nt[i])
169         dep[to[i]] = dep[u] + 1, build(to[i]);
170 }
171
172 inline void prework(void)
173 {
174     spfa();
175
176     tarjan(1, 0);
177
178     for (int i = 1; i <= 20; ++i)
179         for (int j = 1; j <= n; ++j)
180             fat[j][i] = fat[fat[j][i - 1]][i - 1];
181
182     memset(hd, -1, sizeof hd), tot = 0;
183
184     for (int i = 2; i <= n; ++i)
186
187     dep[1] = 1, build(1);
188 }
189
190 inline int getLCA(int a, int b, int &x, int &y)
191 {
192     if (dep[a] < dep[b])
193         a ^= b ^= a ^= b;
194
195     int ret = dis[a] + dis[b];
196
197     for (int i = 20; ~i; --i)
198         if (dep[fat[a][i]] >= dep[b])
199             a = fat[a][i];
200
201     if (a == b)
202         return x = y = a, ret - dis[a] * 2;
203
204     for (int i = 20; ~i; --i)
205         if (fat[a][i] != fat[b][i])
206             a = fat[a][i],
207             b = fat[b][i];
208
209     return x = a, y = b, ret - dis[fat[a][0]] * 2;
210 }
211
212 signed main(void)
213 {
214     n = nextInt();
215     m = nextInt();
216     q = nextInt();
217
218     memset(hd, -1, sizeof(hd)), tot = 0;
219
220     for (int i = 1; i <= m; ++i)
221     {
222         int x = nextInt();
223         int y = nextInt();
224         int w = nextInt();
225
228     }
229
230     prework();
231
232     for (int i = 1, x, y; i <= q; ++i)
233     {
234         int a = nextInt();
235         int b = nextInt();
236
237         int ans = getLCA(a, b, x, y);
238
239         if (bel[x] && bel[x] == bel[y])
240         {
241             ans = dis[a] + dis[b] - dis[x] - dis[y];
242
243             int len1 = abs(cir[x] - cir[y]);
244             int len2 = len[bel[x]] - len1;
245
246             ans += min(len1, len2);
247         }
248
249         printf("%d\n", ans);
250     }
251 }

@Author: YouSiki

posted @ 2017-02-25 16:19  YouSiki  阅读(...)  评论(...编辑  收藏