ZOJ3223:Journey to the Center of the Earth

——problem:n个点,边有两种,一种是普通的路,一种是近道,求在规定时间内从起点到终点用的最少的近道数是多少。

——solution:二维DIJKSTRA

一开始犯傻了,二分用的近道数,看能不能再规定时间内到达……结果超时。

其实直接求DIST[I][J]就好了,然后找个J最小的且在规定时间的的J就是答案了。

结果还是超时……感觉50*100*100*100应该不会超……

看了下题解,有个小优化,Limit初始为近道数。

每次到终点时记录下用的近道数,如果比LIMIT小就更新,这样如果当前状态用的近道数比limit还大的话就直接忽略。

View Code
1 #include<stdio.h>
2 #include<queue>
3 #include<memory.h>
4  using namespace std;
5  #define oo 2000000000
6  #define V 105
7  #define E 40000
8  int i, j, ans, u, v, l, n, m, s, t, num, num_s, sum_shortcut, T;
9 int dist[V][E], head[V], nxt[E], ev[E], ew[E], head_s[V], nxt_s[E], ev_s[E],
10 ew_s[E];
11 bool vis[V][E];
12 struct node
13 {
14 int u, l, s;
15 friend bool operator <(node a, node b)
16 {
17 return a.l > b.l;
18 }
19 node(int a = 0, int b = 0, int c = 0) :
20 u(a), l(b), s(c)
21 {
22 }
23 } x, y;
24 void add_edge(int u, int v, int l)
25 {
26 nxt[++num] = head[u];
27 head[u] = num;
28 ev[num] = v;
29 ew[num] = l;
30 }
31 void add_shortcut(int u, int v, int l)
32 {
33 nxt_s[++num_s] = head_s[u];
34 head_s[u] = num_s;
35 ev_s[num_s] = v;
36 ew_s[num_s] = l;
37 }
38 int dijkstra()
39 {
40 int i, j, limit;
41 priority_queue<node> q;
42 memset(vis, 0, sizeof(vis));
43 for (i = 1; i <= n; i++)
44 for (j = 0; j <= sum_shortcut; j++)
45 dist[i][j] = oo;
46 limit = sum_shortcut;
47 dist[s][0] = 0;
48 q.push(node(s, 0, 0));
49 while (!q.empty())
50 {
51 x = q.top();
52 q.pop();
53 if (x.u == t && x.s < limit) //优化
54 limit = x.s;
55 if (!vis[x.u][x.s])
56 {
57 for (i = head[x.u]; i; i = nxt[i])
58 {
59 y.u = ev[i];
60 y.l = x.l + ew[i];
61 y.s = x.s;
62 if (y.l < dist[y.u][y.s] && y.l <= T)
63 {
64 dist[y.u][y.s] = y.l;
65 q.push(y);
66 }
67 }
68 if (x.s < limit)
69 for (i = head_s[x.u]; i; i = nxt_s[i])
70 {
71 y.u = ev_s[i];
72 y.l = x.l + ew_s[i];
73 y.s = x.s + 1;
74 if (y.l < dist[y.u][y.s] && y.l <= T)
75 {
76 dist[y.u][y.s] = y.l;
77 q.push(y);
78 }
79 }
80 }
81 vis[x.u][x.s] = true;
82 }
83 for (i = 0; i <= sum_shortcut; i++)
84 if (dist[t][i] <= T)
85 return i;
86 return -1;
87 }
88 int main()
89 {
90 while (scanf("%d%d", &n, &m) != EOF)
91 {
92 num = 0;
93 num_s = 0;
94 memset(head, 0, sizeof(head));
95 memset(nxt, 0, sizeof(nxt));
96 memset(head_s, 0, sizeof(head_s));
97 memset(nxt_s, 0, sizeof(nxt_s));
98 for (i = 0; i < m; i++)
99 {
100 scanf("%d%d%d", &u, &v, &l);
101 add_edge(u, v, l);
102 add_edge(v, u, l);
103 }
104 scanf("%d", &sum_shortcut);
105 for (i = 0; i < sum_shortcut; i++)
106 {
107 scanf("%d%d%d", &u, &v, &l);
108 add_shortcut(u, v, l);
109 add_shortcut(v, u, l);
110 }
111 scanf("%d%d", &s, &t);
112 scanf("%d", &T);
113 ans = dijkstra();
114 if (ans != -1)
115 printf("%d\n", ans);
116 else
117 printf("Impossible\n");
118 }
119 return 0;
120 }
posted on 2011-03-25 22:06  风也轻云也淡  阅读(179)  评论(0编辑  收藏  举报