intf(string& s){ int res = 0; for (int i = 0; i < 9; i++) { if (s[i] == 'x') continue; int n = s[i] - '1'; res += abs(n/3-i/3) + abs(n%3-i%3); } return res; }
string astar(){ q.push({f(start), start}); dist[start] = 0; while (q.size()) { pis p = q.top(); q.pop(); string cur = p.second; if (cur == target) break; int idx = cur.find('x'), tx = idx/3, ty = idx%3; for (int i = 0; i < 4; i++) { int x = tx+dx[i], y = ty+dy[i]; if (x < 0 || x >= 3 || y < 0 || y >= 3) continue; string child = cur; swap(child[x*3+y], child[tx*3+ty]); if (dist.count(child) == 0 || dist[child] > dist[cur] + 1) { dist[child] = dist[cur]+1; pre[child] = {way[i], cur}; q.push({dist[child] + f(child), child}); } } } string ans, t = target; while (t != start) { auto p = pre[t]; t = p.second; ans += p.first; } reverse(ans.begin(), ans.end()); return ans; }
intmain(){ for (int i = 0; i < 9; i++) { char ch; cin >> ch; start += ch; } // 逆序对数量 int cnt = 0; for (int i = 0; i < 9; i++) { for (int j = i+1; j < 9; j++) { if (start[j] == 'x' || start[i] == 'x') continue; if (start[j] < start[i]) cnt++; } } if (cnt & 1) cout << "unsolvable"; else cout << astar(); return0; }
第 K 短路
给定一张 N 个点(编号 1,2…N),M 条边的有向图,求从起点 S 到终点 T 的第 K 短路的长度,路径允许重复经过点或边。
// 建反向图 边数比它给的乘2 typedef pair<int, int> pii; typedef pair<int, pii> piii; constint N = 1010, M = 2e4+10; int n, m, S, T, K; int h[N], rh[N], e[M], ne[M], w[M], idx; int dist[N];
voidadd(int h[], int a, int b, int c){ e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++; }
voiddj(){ memset(dist, 0x3f, sizeof dist); dist[T] = 0; priority_queue<pii, vector<pii>, greater<pii>> heap; heap.push({0, T}); while (heap.size()) { pii _t = heap.top(); heap.pop(); int t = _t.second; // 这里是反向图!! for (int i = rh[t]; ~i; i = ne[i]) { int j = e[i]; if (dist[j] > dist[t] + w[i]) { dist[j] = dist[t] + w[i]; heap.push({dist[j], j}); } } } }
intastar(){ priority_queue<piii, vector<piii>, greater<piii>> heap; // 估价距离 到原点距离 点 // 因为它不是单纯最短路 所以需要记录一下到原点的距离 heap.push({dist[S], {0, S}}); int cnt = 0; while (heap.size()) { piii _t = heap.top(); heap.pop(); int t = _t.second.second, distance = _t.second.first; if (t == T) cnt++; if (cnt == K) return distance; for (int i = h[t]; ~i; i = ne[i]) { int j = e[i]; // 跳过不可达到终点的节点 if (dist[j] == 0x3f3f3f3f) continue; heap.push({distance + w[i] + dist[j], {distance + w[i], j}}); } } return-1; }
intmain(){ cin >> n >> m; memset(h, -1, sizeof h); memset(rh, -1, sizeof rh); for (int i = 0; i < m; i++) { int a, b, c; cin >> a >> b >> c; add(h, a, b, c); add(rh, b, a, c); } cin >> S >> T >> K; if (S == T) K++; dj(); cout << astar(); return0; }