A*算法:算出每一个点的g[x],h[x];
g[x]:走到当前点的指。
h[x]:当前点到终点的预计值。这个值应该小于等于实际值。
然后每次取g[x]+h[x]最小的一个做为选取点。
当第k次选到终点的时候,终点走到了k次。
#include <iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<stdlib.h> #include<vector> #include<cmath> #include<queue> #include<set> #include<map> using namespace std; #define maxn 210000 #define maxeg 110000 #define maxpt 1100 #define INF 99999999 struct G { int num; int head[maxpt]; struct list{int u,v,w,next;}edge[maxeg]; void init(){ memset(head,-1,sizeof(head)); num=0; } void add(int u,int v,int w){ edge[num].u=u;edge[num].v=v;edge[num].w=w; edge[num].next=head[u];head[u]=num++; } }gra,fgra; struct list { int u; int g; int h; bool operator < (const list &a)const{ return g+h>a.g+a.h; } }p,pp; int n,m; int h[maxpt]; void dij(int x) { int i; int vis[maxpt]; for(i=0;i<maxpt;i++){ vis[i]=0;h[i]=INF; } h[x]=0; while(1) { int minn=INF; int u; for(i=1;i<=n;i++) { if(!vis[i]&&h[i]<minn) { minn=h[i]; u=i; } } if(minn==INF)break; vis[u]=1; for(i=fgra.head[u];i!=-1;i=fgra.edge[i].next) { int v=fgra.edge[i].v; int w=fgra.edge[i].w; if(vis[v])continue; if(h[v]>h[u]+w)h[v]=h[u]+w; } } } priority_queue<list>que; int AS(int s,int t,int k) { int times[maxpt]; memset(times,0,sizeof(times)); while(!que.empty())que.pop(); p.u=s;p.g=0;p.h=h[s];que.push(p); while(!que.empty()) { p=que.top();que.pop(); times[p.u]++; if(times[p.u]==k&&p.u==t)return p.g; // if(times[p.u]>k)continue; for(int i=gra.head[p.u];i!=-1;i=gra.edge[i].next) { int v=gra.edge[i].v; int g=gra.edge[i].w+p.g; pp.u=v;pp.g=g;pp.h=h[v]; que.push(pp); } } return -1; } int main() { int i,a,b,c,s,t,k; while(~scanf("%d%d",&n,&m)) { gra.init(); fgra.init(); for(i=1;i<=m;i++) { scanf("%d%d%d",&a,&b,&c); gra.add(a,b,c); fgra.add(b,a,c); } scanf("%d%d%d",&s,&t,&k); if(s==t)k++; dij(t); cout<<AS(s,t,k)<<endl; } return 0; }