——url:http://acm.hdu.edu.cn/showproblem.php?pid=2992
——problem: 有n(≤10000)个地点, m(≤100000)条无向边, 其中有h个地点建有旅馆, 一个人从1出发去n, 此人每天最多走10小时, 然后就要进旅馆休息, 第二天继续走, 直到到达n, 问最少需要预定多少家旅馆(最少需要多少天)可以到达n, 若不能到达则输出-1.
——solution: h次Dijkstra求出旅馆间最短路, 然后重新建图再做一次最短路。
把起点和终点也当做旅馆。对每个旅馆做次最短路,如果两个旅馆之间的时间<=600,那么这两个旅馆能隔天到达,重新建图,如果两个旅馆的最短时间<=600就连一条权为1的边。
做完k次最短路后再新的图上做次最短路,答案就是DIST[N]-1.另外,由于旅馆最多就100个,第二次可以不用DIJSTRA,直接BFS就可以了。
问题:
1、边有100000条,一开始看错了,少开了一位。
2、关于建新图的问题,显然每个旅馆看做一个节点,要对他们重新编号。如果本身输入中的旅馆就有起点和终点,小心重复编号。
我做的时候旅馆的编号就是输入时的顺序,然后又开了个TAG数组,记录新图中的节点对应原图中的哪个节点。
————————————————————————————————————————————————————————————————————
1 #include<stdio.h>
2 #include<queue>
3 using namespace std;
4 #define E 300000
5 #define V 30000
6 #define typec int // type of cost
7 const typec inf = 0x3f3f3f3f; // max of cost
8 typec cost[E], dist[V];
9 int h, n, m, e, ans;
10 int pnt[E], nxt[E], head[V], vis[V], hot[105], tag[V],map[105][105] ;
11 struct qnode
12 {
13 int v;
14 typec c;
15 qnode(int vv = 0, typec cc = 0) :
16 v(vv), c(cc)
17 {
18 }
19 bool operator <(const qnode& r) const
20 {
21 return c > r.c;
22 }
23 };
24 void dijkstra(int n, const int src)
25 {
26 qnode mv;
27 int i, j, k, pre;
28 priority_queue<qnode> que;
29 memset(vis, 0, sizeof(vis));
30 for (i = 1; i <= n; i++)
31 dist[i] = inf;
32 vis[src] = 1;
33 dist[src] = 0;
34 que.push(qnode(src, 0));
35 for (pre = src, i = 1; i < n; i++)
36 {
37 for (j = head[pre]; j != -1; j = nxt[j])
38 {
39 k = pnt[j];
40 if (vis[k] == 0 && dist[pre] + cost[j] < dist[k]&&dist[pre] + cost[j]<=600)
41 {
42 dist[k] = dist[pre] + cost[j];
43 que.push(qnode(pnt[j], dist[k]));
44 }
45 }
46 while (!que.empty() && vis[que.top().v] == 1)
47 que.pop();
48 if (que.empty())
49 break;
50 mv = que.top();
51 que.pop();
52 vis[pre = mv.v] = 1;
53 }
54 }
55 inline void addedge(int u, int v, typec c)
56 {
57 pnt[e] = v;
58 cost[e] = c;
59 nxt[e] = head[u];
60 head[u] = e++;
61 }
62 int BFS(int s, int t)
63 {
64 bool flag[105];
65 int i;
66 qnode x, y;
67 queue<qnode> q;
68 memset(flag, 0, sizeof(flag));
69 flag[s] = true;
70 x.v = s;
71 x.c = 0;
72 q.push(x);
73 while (!q.empty())
74 {
75 x = q.front();
76 q.pop();
77 if (x.v == t)
78 return x.c-1;
79 for (i = 1; i <= h; i++)
80 if (map[x.v][i] == 1 && flag[i] == false)
81 {
82 flag[i] = true;
83 y.v = i;
84 y.c = x.c + 1;
85 q.push(y);
86 }
87 }
88 return -1;
89 }
90 int main()
91 {
92 int i, j, u, v;
93 typec c;
94 freopen("hotel.in","r",stdin);
95 while (1)
96 {
97 memset(head, -1, sizeof(head));
98 memset(nxt, -1, sizeof(nxt));
99 memset(tag, 0, sizeof(tag));
100 memset(map, 0, sizeof(map));
101 e = 0;
102 scanf("%d", &n);
103 if (n == 0)
104 break;
105 scanf("%d", &h);
106 for (i = 1; i <= h; i++)
107 {
108 scanf("%d", &hot[i]);
109 tag[hot[i]] = i;
110 }
111 if (tag[1] == 0)
112 {
113 tag[1] = ++h;
114 hot[h]=1;
115 }
116 if (tag[n] == 0)
117 {
118 tag[n] = ++h;
119 hot[h]=n;
120 }
121 scanf("%d", &m);
122 for (i = 0; i < m; ++i)
123 {
124 scanf("%d%d%d", &u, &v, &c);
125 addedge(u, v, c);
126 addedge(v, u, c);
127 }
128 for (i = 1; i <= h; i++)
129 if (hot[i] != n)
130 {
131 dijkstra(n, hot[i]);
132 for (j = 1; j <= h; j++)
133 if (dist[hot[j]] <= 600)
134 {
135 map[i][j] = 1;
136 map[j][i] = 1;
137 }
138 }
139 ans = BFS(tag[1], tag[n]);
140 printf("%d\n",ans);
141 }
142 return 0;
143 }