版权声明:随意转载,转载请注明出处。 https://blog.csdn.net/qq_36258516/article/details/81937701
Hot Pursuit II(次短路Astar算法)
Hot Pursuit II |
---|
Time Limit: 1000 MSMemory Limit: 65536 KTotal Submit: 80(34 users)Total Accepted: 41(27 users)Rating: ![]() ![]() ![]() ![]() |
Description |
Liuctic is a great fan of Need For Speed, the most popular racing game on PC platform. He has played from NFS 3 to NFS 12 in the past 8 years. However, his favourate is NFS 6, named Hot Pursuit II. Hot Pursuit II is a story of racers and police. The racers have great cars and always race on the street. The police hide nearly everywhere to pursuit these mad drivers. They sometimes use helicopters, roadblocks and heavy SUV cars. So the police is a big headache of racing. If followed by several police cars, you hardly can win the race. Hot Pursuit II is based on an open map, which means there’re several different ways leading to the finishing line. You can choose whichever you like. Liuctic is quite familiar of the map. He has driven on them nearly a thousand times, he can easily tell which road is the shortest. But he found that the shortest road hides more police than the others. He wants to win the race, so the shortest road is not always the best choice. Though the second shortest road may share a few paths with the shortest one, it reduces the probability of police’s appearance. Then he decides to drive on the second shortest road. His experience can not tell which road is the second shortest, so he needs some calculation. He cracked the data file and found the maps is stored in the following format: m N1 a11 v11 a12 v12 a13 v13… N2 a21 v21 a22 v22 a23 v23 … … Nm am1 vm1 am2 vm2 am3 vm3 … It begins with an integer m, the number of places. Then m lines followed. The i-th line describes the i-th place. Ni is the number of adjacent places of the i-th place, followed by Ni pairs of positive integers. Each pair is made up of an index of a place, and the distance(<10000) from the i-th place to itself. The roads are all uni-directional and the indices of the pairs are different(for example, if the i-th place and the j-th place ARE ADJACENT, there is at most one road from i to j, and at most one road from j to i). The index starts from 1. m<1000, Ni<100. |
Input |
There’re several maps. The input data ensures that there are more than 1 path from place 1 to place m. Input ends with EOF. Suppose the shortest length is S, if there’re more than one path with the length S, we can say S is also the second shortest length. |
Output |
For each map,output the length of the second shortest road from place 1 to place m in a single line. |
Sample Input |
3 2 2 1 3 1 1 3 2 1 1 2 3 2 2 1 3 1 1 3 2 1 1 2 |
Sample Output |
3 3 |
题意
n个点,每个点有m条有向边,最后询问从1到n的第2短的路。
解题思路
k短路问题,最有效的就是A* 算法。A* 算法最重要的是估值函数,在k短路问题中,显然可以知道,估值函数就是当前走过的路+剩余的路。剩余的路,我们可以用dijkstra反向跑图,就可以得到每个点距离终点的距离;走过的路我们可以用BFS。最后利用优先队列,将估值函数小的值排到前面。最后走到终点的时候,第k短的路是第k次到达终点的路。
代码
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<string.h>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxm = 1e3+50;
int n,m,vis[maxm],d[maxm],s,t,k;
struct node
{
int x,val;
node() {}
node(int a,int b):x(a),val(b) {}
friend bool operator < (node a,node b)
{
return a.val>b.val;
}
};
vector<node> v[maxm],_v[maxm];
void init()
{
for(int i=0; i<maxm; i++)
{
v[i].clear();
_v[i].clear();
}
}
void dijkstra(int t)
{
memset(d,inf,sizeof d);
memset(vis,0,sizeof vis);
d[t]=0;
priority_queue<node> q;
while(!q.empty()) q.pop();
q.push(node(t,0));
while(!q.empty())
{
node x=q.top();
q.pop();
if(vis[x.x]) continue;
vis[x.x]=1;
int len=_v[x.x].size();
for(int i=0; i<len; i++)
{
node y=_v[x.x][i];
if(!vis[y.x]&&d[y.x]>x.val+y.val)
{
d[y.x]=x.val+y.val;
q.push(node(y.x,d[y.x]));
}
}
}
}
struct road
{
int x,h,g;
road() {}
road(int a,int b,int c):x(a),h(b),g(c) {}
friend bool operator <(road a,road b)
{
return a.h+a.g>b.h+b.g;
}
};
void Astar()
{
priority_queue<road> q;
while(!q.empty()) q.pop();
q.push(road(s,0,d[s]));
int cnt=0;
while(!q.empty())
{
road now=q.top();
q.pop();
if(now.x==t) cnt++;
if(cnt>=k)
{
printf("%d\n",now.h);
return;
}
int len=v[now.x].size();
for(int i=0; i<len; i++)
{
node next=v[now.x][i];
q.push(road(next.x,now.h+next.val,d[next.x]));
}
}
printf("-1\n");
}
int main()
{
#ifdef DEBUG
freopen("in.txt","r",stdin);
#endif // DEBUG
while(~scanf("%d",&n))
{
init();
int y,z;
for(int i=1;i<=n;i++)
{
scanf("%d",&m);
for(int j=0;j<m;j++)
{
scanf("%d%d",&y,&z);
v[i].push_back(node(y,z));
_v[y].push_back(node(i,z));
}
}
k=2,s=1,t=n;
dijkstra(t);
Astar();
}
return 0;
}