这题要求出第k短路的长度
对于第k短路 , 我们一般都是用A* + SPFA算法 ,
首先 , 我们先求求出所有点到终点的最短路径长度 , 并把这些长度 , 最为估价函数的一部分
然后,我们再用bfs、优先队列、加上A*算法思想 , 就能得到第k短路的长度
对于第k短路 , 我们只需要在优先队列中第k次遍历到终点时 , 那么这个路径长度就是第k短路的长度,因为我们在使用优先队列时 , 最先出队的 , 肯定是状态最优的 , 因此第k次出队列的, 那么肯定是第k优的。
有一个特殊情况 , 当终点和起点相同时 , 我们应该求到第k+1短路 , 因此当起点和终点一样时 , 最优的(或则第一次出队的)肯定是长度为0的点 , 所以这个状态是不能算入进去的 , 因为求两点的路径长度,肯定是要经过一些其他点的
关于A*算法
我们认为不应该把A*认为是一种算法, 只能把它看做是一种思想 , 对于搜索时的优先思想 , 就像搜索时使用优先队列一样 , 这也能看做是一种A* , 因此A*只是一种思想,并且这种思想的不确定性非常大 。
代码:
//A* + SPFA 求第k短路径长度
#include
#include
#include
#include
#include
using namespace std;
#define INF 0xfffffff
#define maxn 1010
struct node
{
int to;
int w;
};
struct node1
{
int to;
int g , f;
bool operator <(const node1 &r)
const
{
if(r.f == f)
return r.g < g;
return r.f < f;
}
};
vectorgrap[maxn];
vectorfgrap[maxn];
int dist[maxn];
int n , m , k , sx , ty;
void init()
{
for(int i = 1; i <= n; i++)
{
grap[i].clear();
fgrap[i].clear();
}
}
void SPFA()
{
int pre[maxn] , i , y;
memset(pre , 0 , sizeof(pre));
queueq;
q.push(ty);
for(i = 1; i <= n; i++)
dist[i] = INF;
dist[ty] = 0;
while(!q.empty())
{
int x = q.front();
q.pop();
pre[x] = 0;
for(i = 0; i < fgrap[x].size(); i++)
{
y = fgrap[x][i].to;
if(dist[y] > dist[x]+fgrap[x][i].w)
{
dist[y] = dist[x]+fgrap[x][i].w;
if(!pre[y])
q.push(y) , pre[y] = 1;
}
}
}
}
int a_star()
{
int cnt = 0 , x , i;
node1 u , v;
priority_queueq;
if(dist[sx] == INF)
return -1;
if(sx == ty)
k += 1;
u.to = sx;
u.g = 0; u.f = u.g+dist[sx];
q.push(u);
while(!q.empty())
{
u = q.top();
q.pop();
x = u.to;
if(x == ty)
cnt += 1;
if(cnt == k)
return u.g;
for(i = 0; i < grap[x].size(); i++)
{
v.to = grap[x][i].to;
v.g = u.g+grap[x][i].w;
v.f = v.g + dist[v.to];
q.push(v);
}
}
return -1;
}
int main()
{
while(scanf("%d %d" , &n , &m) != EOF)
{
init();
int i , x , y , z;
node u;
for(i = 0; i < m; i++)
{
scanf("%d %d %d" , &x , &y , &z);
u.to = y;
u.w = z;
grap[x].push_back(u);
u.to = x;
fgrap[y].push_back(u);
}
scanf("%d %d %d" , &sx , &ty , &k);
SPFA();
x = a_star();
cout<<x<<endl;
}
return 0;
}
对于第k短路 , 我们一般都是用A* + SPFA算法 ,
首先 , 我们先求求出所有点到终点的最短路径长度 , 并把这些长度 , 最为估价函数的一部分
然后,我们再用bfs、优先队列、加上A*算法思想 , 就能得到第k短路的长度
对于第k短路 , 我们只需要在优先队列中第k次遍历到终点时 , 那么这个路径长度就是第k短路的长度,因为我们在使用优先队列时 , 最先出队的 , 肯定是状态最优的 , 因此第k次出队列的, 那么肯定是第k优的。
有一个特殊情况 , 当终点和起点相同时 , 我们应该求到第k+1短路 , 因此当起点和终点一样时 , 最优的(或则第一次出队的)肯定是长度为0的点 , 所以这个状态是不能算入进去的 , 因为求两点的路径长度,肯定是要经过一些其他点的
关于A*算法
代码:
//A* + SPFA 求第k短路径长度
#include
#include
#include
#include
#include
using namespace std;
#define INF 0xfffffff
#define maxn 1010
struct node
{
};
struct node1
{
};
vectorgrap[maxn];
vectorfgrap[maxn];
int dist[maxn];
int n , m , k , sx , ty;
void init()
{
}
void SPFA()
{
}
int a_star()
{
}
int main()
{
}