1 条题解
-
1
C++ :
#include <cstring> #include <iostream> #include <algorithm> #include <queue> using namespace std; typedef pair<int, int> PII; typedef pair<int, PII> PIII; const int N = 1001, M = 200001; int n, m, S, T, K; int h[N], rh[N], e[M], w[M], ne[M], idx; int dist[N], cnt[N]; bool st[N]; void add(int h[],int a,int b,int c) { e[idx] = b; w[idx] = c; ne[idx] = h[a]; h[a] = idx++; } void dijkstra() { priority_queue< PII,vector<PII>,greater<PII> > heap; heap.push({0,T});//终点 memset(dist, 0x3f, sizeof dist); dist[T] = 0; while(heap.size()) { PII t = heap.top(); heap.pop(); int ver = t.second; // if(st[ver]) continue; // st[ver] = true; for(int i=rh[ver];i!=-1;i=ne[i]) { int j = e[i]; if(dist[j]>dist[ver]+w[i]) { dist[j] = dist[ver] + w[i]; heap.push({dist[j],j}); } } } } int astar() { priority_queue< PIII, vector<PIII>, greater<PIII> > heap; // 谁的d[u]+f[u]更小 谁先出队列 heap.push({dist[S], {0, S}}); while(heap.size()) { PIII t = heap.top(); heap.pop(); int ver = t.second.second,distance = t.second.first; cnt[ver]++; //如果终点已经被访问过k次了 则此时的ver就是终点T 返回答案 if(cnt[T]==K) return distance; for(int i=h[ver];i!=-1;i=ne[i]) { int j = e[i]; if(cnt[j] < K) { // 按 真实值+估计值 = d[j]+f[j] = dist[S,t] + w[t][j] + dist[j,T] 堆排 // 真实值 distance+w[i] heap.push({distance+w[i]+dist[j],{distance+w[i],j}}); } } } // 终点没有被访问k次 return -1; } int main() { cin >> n >> m; memset(h,-1,sizeof h); memset(rh,-1,sizeof rh); while(m--) { int a,b,c; cin >> a >> b >> c; add(h,a,b,c); add(rh,b,a,c); } cin >> S >> T >> K; // 起点==终点时 则d[S→S] = 0 这种情况就要舍去 ,总共第K大变为总共第K+1大 if (S == T) K ++ ; // 从各点到终点的最短路距离 作为估计函数f[u] dijkstra(); cout << astar(); return 0; }
- 1
信息
- ID
- 89
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 1
- 标签
- 递交数
- 45
- 已通过
- 35
- 上传者