k短路
题
我果然已经傻到这种地步了,
A*不只要在有向图里BFS就不会重边了吗!!!
我到底已经傻到什么地步了!!
好吧,言归正传,首先dijistra求出终点的所有单源最短路,然后从起点开始\(A*\)。
函数为 $$f(x) = dis(i)+d(i)$$
\(dis(i)\) 为当前所走路径,\(d(i)\) 为到终点路径
然后开个优先队列搜索就可以了,每次到终点就记录答案。
当然,求k短路还有yen算法和MPS算法。
同时 \(A*\) 会被环卡。
当然,这题的题干保证了没环。
如果有有向环的话 \(A*\) 算法会失效。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<vector>
#include<cstring>
using namespace std;
struct Edge{
int from,to;
double dist;
Edge(int from,int to,double dist):from(from),to(to),dist(dist){}
bool operator < (const Edge& A)const{
return dist > A.dist;
}
};
const int maxn = 19999;
struct HeapNode{
int to,dist;
bool operator < (const HeapNode& rhs)const{
return dist > rhs.dist;
}
};
struct ANode{
int id,dis,g;
bool operator < (const ANode& rhs)const{
return dis+g > rhs.dis+rhs.g;
}
};
const int INF = ~0U>>1;
struct solve{
int n,m;
int d[maxn];
int vis[maxn];
int ans[maxn];
vector<Edge> edges;
vector<int> G[maxn];
void addedge(int from,int to,int dist){
edges.push_back(Edge(from,to,dist));
int m = edges.size();
G[from].push_back(m-1);
}
void init(int n,int m){
this->n = n;this-> m = m;
for(int i = 0;i <= n;i++) d[i] = INF;
memset(vis,0,sizeof(vis));
memset(ans,-1,sizeof(ans));
ans[0] = 0;
}
void dijistra(int s){
priority_queue<HeapNode> Q;
Q.push((HeapNode){s,0});
d[s] = 0;
while(!Q.empty()){
HeapNode u =Q.top();Q.pop() ;
if(vis[u.to]) continue;
vis[u.to] = 1;
for(int i = 0;i < G[u.to].size();i++){
Edge e = edges[G[u.to][i]];
if(d[e.to] > d[e.from]+e.dist){
d[e.to] = d[e.from] + e.dist;
}
}
}
}
void Astar(int s){
priority_queue<ANode> Q;
Q.push((ANode){s,0,d[s]});
while(!Q.empty()){
ANode u = Q.top();Q.pop();
if(u.id == n){ans[++ans[0]] = u.dis;if(ans[0] > m) break;continue;}
for(int i = 0;i < G[u.id].size();i++){
Edge e = edges[G[u.id][i]];
Q.push((ANode){e.to,u.dis+e.dist,d[e.to]});
}
}
for(int i = 1;i<= m;i++) printf("%d\n",ans[i]);
}
}solver;
int from[maxn],to[maxn],dist[maxn];
int main()
{
freopen("cowjog.in","r",stdin);
freopen("cowjog.out","w",stdout);
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
for(int i = 0;i < m;i++){
scanf("%d%d%d",&from[i],&to[i],&dist[i]);
solver.addedge(from[i],to[i],dist[i]);
}
solver.dijistra(n);
solver.init(n,k);
solver.edges.clear();
for(int i = 0;i <= n;i++) solver.G[i].clear();
for(int i = 0;i < m;i++){
solver.addedge(to[i],from[i],dist[i]);
}
solver.Astar(1);
return 0;
}

浙公网安备 33010602011771号