1 #include <iostream>
2 #include <vector>
3 #include <cstdio>
4 #include <queue>
5 #include <utility>
6 #include <stack>
7 using namespace std;
8
9 const int MAXN = 505;
10 const int inf = 0x3f3f3f3f;
11
12 typedef struct _node
13 {
14 int v, w;
15 }N;
16
17 vector<N> vec[MAXN];
18 stack<int> S;
19 int scc, dfn[MAXN], low[MAXN], step;
20 int inS[MAXN], id[MAXN];
21
22 //spfa
23 vector<N> sccvec[MAXN];
24
25 void deal_spfa(int n)
26 {
27 N tmp;
28 int u, v;
29 for(int i = 1; i <= n; i++)
30 {
31 for(unsigned j = 0; j < vec[i].size(); j++)
32 {
33 u = i, v = vec[i][j].v;
34 if(id[u] == id[v])
35 continue;
36 else
37 {
38 tmp.v = id[v];
39 tmp.w = vec[i][j].w;
40 sccvec[id[u]].push_back(tmp);
41 }
42 }
43 }
44 }
45
46 int spfa(int s, int e)
47 {
48 queue<int> Q;
49 int dis[MAXN], in[MAXN] = {0};
50 for(int i = 0; i < MAXN; i++)
51 dis[i] = inf;
52 dis[s] = 0;
53 in[s] = 1;
54 Q.push(s);
55 while(!Q.empty())
56 {
57 int pre = Q.front();
58 Q.pop();
59 in[pre] = 0;
60 for(unsigned i = 0; i < sccvec[pre].size(); i++)
61 {
62 int son = sccvec[pre][i].v;
63 int w = sccvec[pre][i].w;
64 if(dis[son] > dis[pre] + w)
65 {
66 dis[son] = dis[pre] + w;
67 if(in[son] == 0)
68 {
69 Q.push(son);
70 in[son] = 1;
71 }
72 }
73 }
74 }
75
76 return dis[e];
77 }
78
79 void init()
80 {
81 while(!S.empty())
82 S.pop();
83 step = 0;
84 scc = 1;
85 for(int i = 0; i < MAXN; i++)
86 {
87 sccvec[i].clear();
88 id[i] = 0;
89 inS[i] = 0;
90 dfn[i] = low[i] = -1;
91 vec[i].clear();
92 }
93 }
94
95 void addEdge(int u, int v, int w)
96 {
97 N tmp;
98 tmp.v = v, tmp.w = w;
99 vec[u].push_back(tmp);
100 }
101
102 void tarjan_scc(int n)
103 {
104 dfn[n] = low[n] = ++step;
105 S.push(n);
106 inS[n] = 1;
107 for(unsigned i = 0; i < vec[n].size(); i++)
108 {
109 int son = vec[n][i].v;
110 if(dfn[son] == -1)
111 {
112 tarjan_scc(son);
113 low[n] = min(low[n], low[son]);
114 }
115 else if(inS[son] == 1)
116 {
117 low[n] = min(low[n], dfn[son]);
118 }
119 }
120 if(low[n] == dfn[n] && !S.empty())
121 {
122 //cout << "--------------" << endl;
123 int tmp;
124 do
125 {
126 tmp = S.top();
127 //cout << tmp << " ";
128 S.pop();
129 inS[tmp] = 0;
130 id[tmp] = scc;
131 }while(!S.empty() && tmp != n);
132 //cout << endl;
133 scc++;
134 }
135 }
136
137 int main(void)
138 {
139 #ifndef ONLINE_JUDGE
140 //freopen("in.txt", "r", stdin);
141 #endif
142 //cout << inf << endl;
143 int n, m, cas_c = 0;
144 while(scanf("%d", &n), n)
145 {
146 scanf("%d", &m);
147 if(cas_c++ != 0)
148 printf("\n");
149 int u, v, w;
150 init();
151 for(int i = 0; i < m; i++)
152 {
153 scanf("%d %d %d", &u, &v, &w);
154 addEdge(u, v, w);
155 }
156 for(int i = 1; i <= n; i++)
157 {
158 if(dfn[i] == -1)
159 tarjan_scc(i);
160 }
161
162 //cout << "******" << endl;
163 deal_spfa(n);
164 int q;
165 scanf("%d", &q);
166 for(int i = 0; i < q; i++)
167 {
168 scanf("%d %d", &u, &v);
169 if(id[u] == id[v])
170 printf("0\n");
171 else
172 {
173 int ans = spfa(id[u], id[v]);
174 if(ans == inf)
175 printf("Nao e possivel entregar a carta\n");
176 else
177 printf("%d\n", ans);
178 }
179 }
180 }
181 return 0;
182 }
183
184
185
186 第二次优化时间
187 State: POJ3114 Accepted 3904K 313MS C++ 2878B
188 #include <iostream>
189 #include <vector>
190 #include <cstdio>
191 #include <queue>
192 #include <utility>
193 #include <stack>
194 using namespace std;
195
196 const int MAXN = 505;
197 const int MAXE = 250005;
198 const int inf = 0x3f3f3f3f;
199
200 typedef struct _node
201 {
202 int v, w;
203 int next;
204 }N;
205
206 N edge[MAXE];
207 int scc, dfn[MAXN], low[MAXN], step, myS[MAXN], top;
208 int inS[MAXN], id[MAXN], cntEdge, head[MAXN];
209
210 //spfa
211 vector<N> sccvec[MAXN];
212
213 void deal_spfa(int n)
214 {
215 N tmp;
216 int u, v;
217 for(int i = 1; i <= n; i++)
218 {
219 for(int j = head[i]; j != -1; j = edge[j].next)
220 {
221 u = i, v = edge[j].v;
222 if(id[u] == id[v])
223 continue;
224 else
225 {
226 tmp.v = id[v];
227 tmp.w = edge[j].w;
228 sccvec[id[u]].push_back(tmp);
229 }
230 }
231 }
232 }
233
234 int spfa(int s, int e)
235 {
236 queue<int> Q;
237 int dis[MAXN], in[MAXN] = {0};
238 for(int i = 0; i < MAXN; i++)
239 dis[i] = inf;
240 dis[s] = 0;
241 in[s] = 1;
242 Q.push(s);
243 while(!Q.empty())
244 {
245 int pre = Q.front();
246 Q.pop();
247 in[pre] = 0;
248 for(unsigned i = 0; i < sccvec[pre].size(); i++)
249 {
250 int son = sccvec[pre][i].v;
251 int w = sccvec[pre][i].w;
252 if(dis[son] > dis[pre] + w)
253 {
254 dis[son] = dis[pre] + w;
255 if(in[son] == 0)
256 {
257 Q.push(son);
258 in[son] = 1;
259 }
260 }
261 }
262 }
263
264 return dis[e];
265 }
266
267 void init()
268 {
269 step = cntEdge = top = 0;
270 scc = 1;
271 for(int i = 0; i < MAXN; i++)
272 {
273 sccvec[i].clear();
274 id[i] = 0;
275 inS[i] = 0;
276 dfn[i] = low[i] = -1;
277 head[i] = -1;
278 }
279 }
280
281 void addEdge(int u, int v, int w)
282 {
283 edge[cntEdge].v = v;
284 edge[cntEdge].w = w;
285 edge[cntEdge].next = head[u];
286 head[u] = cntEdge++;
287 }
288
289 void tarjan_scc(int n)
290 {
291 dfn[n] = low[n] = ++step;
292 myS[top++] = n;
293 inS[n] = 1;
294 for(int f = head[n]; f != -1; f = edge[f].next)
295 {
296 int son = edge[f].v;
297 if(dfn[son] == -1)
298 {
299 tarjan_scc(son);
300 low[n] = min(low[n], low[son]);
301 }
302 else if(inS[son] == 1)
303 {
304 low[n] = min(low[n], dfn[son]);
305 }
306 }
307 if(low[n] == dfn[n] && top != 0)
308 {
309 int tmp;
310 do
311 {
312 tmp = myS[--top];
313 inS[tmp] = 0;
314 id[tmp] = scc;
315 }while(top != 0 && tmp != n);
316 scc++;
317 }
318 }
319
320 int main(void)
321 {
322 #ifndef ONLINE_JUDGE
323 freopen("in.txt", "r", stdin);
324 #endif
325 int n, m, cas_c = 0;
326 while(scanf("%d", &n), n)
327 {
328 scanf("%d", &m);
329 if(cas_c++ != 0)
330 printf("\n");
331 int u, v, w;
332 init();
333 for(int i = 0; i < m; i++)
334 {
335 scanf("%d %d %d", &u, &v, &w);
336 addEdge(u, v, w);
337 }
338 for(int i = 1; i <= n; i++)
339 {
340 if(dfn[i] == -1)
341 tarjan_scc(i);
342 }
343
344 deal_spfa(n);
345 int q;
346 scanf("%d", &q);
347 for(int i = 0; i < q; i++)
348 {
349 scanf("%d %d", &u, &v);
350 if(id[u] == id[v])
351 printf("0\n");
352 else
353 {
354 int ans = spfa(id[u], id[v]);
355 if(ans == inf)
356 printf("Nao e possivel entregar a carta\n");
357 else
358 printf("%d\n", ans);
359 }
360 }
361 }
362 return 0;
363 }