int S, T, K, n, m; int hp[N], hn[N], e[M], w[M], ne[M], idx; int cnt[N], dist[N]; bool st[N];
voidadd(int h[], int a, int b, int c) { e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++ ; } voiddijkstra() { memset(st, 0, sizeof st); memset(dist, 0x3f, sizeof dist); priority_queue<PII, vector<PII>, greater<PII>> heap; dist[T] = 0; heap.push({0, T}); while (heap.size()) { PII t = heap.top(); heap.pop();
if (st[t.y]) continue; st[t.y] = true;
for (int i = hn[t.y]; ~i; i = ne[i]) { int j = e[i]; if (dist[j] > dist[t.y] + w[i]) { dist[j] = dist[t.y] + w[i]; heap.push({dist[j], j}); } } } } intf(int id) { return dist[id]; } intastar() { memset(cnt, 0, sizeof cnt); priority_queue<PIII, vector<PIII>, greater<PIII>> heap; heap.push({f(S), {0, S}}); while (heap.size()) { PIII t = heap.top(); heap.pop();
int ver = t.y.y, d = t.y.x; cnt[ver] ++ ; if (cnt[T] == K) return d;
for (int i = hp[ver]; ~i; i = ne[i]) { int j = e[i]; if (cnt[j] < K) heap.push({d + w[i] + f(j), {d + w[i], j}}); } } return-1; } intmain() { cin >> n >> m; memset(hp, -1, sizeof hp); memset(hn, -1, sizeof hn); while (m -- ) { int a, b, c; cin >> a >> b >> c; add(hp, a, b, c); add(hn, b, a, c); } cin >> S >> T >> K; if (S == T) K ++ ;
dijkstra(); cout << astar() << endl; return0; }
八数码
题目描述
在一个 3×3 的网格中,1∼8 这 8 个数字和一个 X 恰好不重不漏地分布在这 3×3 的网格中。
例如:
1 2 3
1 2 3 X 4 6 7 5 8
在游戏过程中,可以把 X 与其上、下、左、右四个方向之一的数字交换(如果存在)。
我们的目的是通过交换,使得网格变为如下排列(称为正确排列):
1 2 3
1 2 3 4 5 6 7 8 X
例如,示例中图形就可以通过让 X 先后与右、下、右三个方向的数字交换成功得到正确排列。
交换过程如下:
1 2 3
1 2 3 1 2 3 1 2 3 1 2 3 X 4 6 4 X 6 4 5 6 4 5 6 7 5 8 7 5 8 7 X 8 7 8 X