Originally thought a A * will be difficult to understand ~ ~ ~ The result of the Fox big Breath to me to understand a * and K short-circuit of the method ....
The so-called a * is the inspiration is search. The plain is to search the BFS a sequence to make the search more reasonable to reduce unnecessary search. How to determine the order of searches ... That is, a value is used to denote this value as f[x]. Every search takes f[x] the smallest expansion ... Then this f[x]=h[x]+g[x] is the price of the current search: H[x. such as the K section of the road this is the previous point of the h[x ']+ side length ... and G[x] is a valuation function. The valuation function is less than the estimate of the current point-to-target cost. This estimate must be less than or equal to the actual value ~ ~ Otherwise it will go wrong ... The key to A * is construction g[x].
And here is to say to ask K short-circuit a method. Is the process of searching with bfs+a* ... g[x] is set to the shortest path to this point to the target point ... Obviously less than equal to the actual value of ... h[x] is the price of searching for this point. To do with a priority queue: Every time you remove h[x]+g[x] The smallest point to expand ... Expansion is the point by which it can be updated directly through an edge. Make a new point here and throw it into the priority queue. Anyway always from the top to the first pop-up h[x]+g[x] the smallest point. Can think about ... If the currently fetched priority queue header is a point E and is the first time to remove H: Then we find a shortest path from source to H. This is actually very djikstra feeling almost. If the second time you remove E from the opponent. is to find a second short path from the source point to H. And so on. The first few times pop from the opponent E. The short path from source to E is found.
What if there is no K-short circuit in itself? That is, E can not expand to K but other points are likely to continue to play the infinite circle ... Here's a condition to judge ... First a certain point was found as the priority queue header appeared several times with a counter times[]. The times[e]==k of the point of the request is understood by the representative. If the current want to expand the point times[]>k there is no need to expand the. Because this point has been to find k+1 short-circuit. From this point to continue to search for sure to get a path greater than or equal to k+1 short-circuit ... Just like 1->2 has 3 roads. 2->3 has 2 roads. That 1->3 has the same concept of 6 paths. There is no need to expand it.
Another thing to pay special attention to is that the topic must go. That is s==e. k++ ....
Add that STL's Priority_queue, STL, already has a priority queue. Like sort can be used directly.
Statement #include <queue>
Define priority_queue< type > variable name
But note that if the structure is used. You need to overload the < in the struct ... As the struct of this problem should be written like this:
struct node
{
int p,g,h;
BOOL operator < (Node A) const
{
return a.g+a.h<g+h;
}
This allows you to prioritize on demand with priority_queue ... Insert with Push: Take the team first with top. Pop up again ... Empty ... What, what? Like a normal queue ... Very good ...
Program:
#include <iostream> #include <queue> #define MAXN 1001 using namespace std;
struct node {int p,g,h;
BOOL operator < (Node A) const {return a.g+a.h<g+h;
}
};
struct Node1 {int x,y,w,next;
}LINE[MAXN*100],LINE1[MAXN*100];
int n,m,i,link[maxn],link1[maxn],g[maxn],s,e,k;
BOOL USED[MAXN];
Priority_queue<node> Myqueue;
void Djikstra () {int i,k,p;
memset (used,0,sizeof (used));
memset (G,0x7f,sizeof (g));
g[e]=0;
for (p=1;p<=n;p++) {k=0;
for (i=1;i<=n;i++) if (!used[i] && (!k | | g[i]<g[k])) k=i;
Used[k]=true;
K=LINK1[K]; while (k) {if (G[LINE1[K].Y]>G[LINE1[K].X]+LINE1[K].W) G[line1[k].y]=g[lin
E1[K].X]+LINE1[K].W;
K=line1[k].next;
}} return;
} int Astar () {int T,TIMES[MAXN]; Node H,temp;
while (!myqueue.empty ()) Myqueue.pop ();
memset (Times,0,sizeof (times)); H.p=s; h.g=0; h.h=0;
Myqueue.push (h);
while (!myqueue.empty ()) {h=myqueue.top ();
Myqueue.pop ();
times[h.p]++;
if (times[h.p]==k && h.p==e) return H.H+H.G;
if (times[h.p]>k) continue;
T=LINK[H.P];
while (t) {TEMP.H=H.H+LINE[T].W;
TEMP.G=G[LINE[T].Y];
TEMP.P=LINE[T].Y;
Myqueue.push (temp);
T=line[t].next;
}} return-1;
} int main () {scanf ("%d%d", &n,&m);
memset (link,0,sizeof (link));
memset (link1,0,sizeof (LINK1));
for (i=1;i<=m;i++) {scanf ("%d%d%d", &LINE[I].X,&LINE[I].Y,&LINE[I].W); Line[i].next=link[line[i].x];
Link[line[i].x]=i; LINE1[I].X=LINE[I].Y; line1[i].y=line[i].x; Line1[i].W=LINE[I].W; Line1[i].next=link1[line1[i].x];
Link1[line1[i].x]=i;
} scanf ("%d%d%d", &s,&e,&k);
if (s==e) k++;
Djikstra ();
printf ("%d\n", Astar ());
return 0;
}