题目链接:http://poj.org/problem?id=2449
K短路的经典题目,直接BFS优先队列扩展超memory,因此要用A*算法优化,先Dijkstal求出所有点到汇点的最短路,注意要把所有边反向,因为是有向图。f(x)=g(x)+h(x),
h(x)是估价函数,当前点到汇点的最短路,g(x)是源点到当前点的花费。因为求出了所有点到汇点的最短路,所以进优先队列时,直接算到达汇点的花费加上到下个点的权值皆可。
当然还有很多其他的算法。
1 //STATUS:G++_AC_297MS_8340KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #include<iostream> 7 #include<string> 8 #include<algorithm> 9 #include<vector> 10 #include<queue> 11 #include<stack> 12 #include<map> 13 using namespace std; 14 #define LL long long 15 #define Max(a,b) ((a)>(b)?(a):(b)) 16 #define Min(a,b) ((a)<(b)?(a):(b)) 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define lson l,mid,rt<<1 19 #define rson mid+1,r,rt<<1|1 20 21 const int MAX=1010,INF=200000000; 22 struct Node{ 23 int d,u; 24 }; 25 struct Edge{ 26 int from,to,dis; 27 }; 28 29 int n,m,S,T,K; 30 int d[MAX],vis[MAX]; 31 vector<Edge> edge1,edge2; 32 vector<int> G1[MAX],G2[MAX]; 33 34 struct cmp1{ 35 bool operator()(const Node &a,const Node &b){ 36 return a.d>b.d; 37 } 38 }; 39 struct cmp2{ 40 bool operator()(const Node &a,const Node &b){ 41 return a.d+d[a.u]>b.d+d[a.u]; 42 } 43 }; 44 45 void init(int n){ 46 edge1.clear(); 47 edge2.clear(); 48 for(int i=1;i<=n;i++) 49 G1[i].clear(); 50 for(int i=1;i<=n;i++) 51 G2[i].clear(); 52 } 53 54 void dijkstra(int s,vector<Edge>& edge){ 55 int i,u; 56 priority_queue<Node,vector<Node>,cmp1> q; 57 for(i=1;i<=n;i++)d[i]=INF;d[s]=0; 58 mem(vis,0); 59 q.push((Node){0,s}); 60 while(!q.empty()){ 61 u=q.top().u;q.pop(); 62 if(vis[u])continue; 63 vis[u]=1; 64 for(i=0;i<G2[u].size();i++){ 65 Edge& e=edge[G2[u][i]]; 66 if(d[u]+e.dis<d[e.to]){ 67 d[e.to]=d[u]+e.dis; 68 q.push((Node){d[e.to],e.to}); 69 } 70 } 71 } 72 } 73 74 int astar(int s,int t,int k,vector<Edge>& edge){ 75 int i; 76 int cou[MAX]; 77 mem(cou,0); 78 Node nod; 79 priority_queue<Node,vector<Node>,cmp2> q; 80 q.push((Node){d[s],s}); 81 if(s==t)k++; 82 while(1){ 83 nod=q.top();q.pop(); 84 if(nod.u==t)cou[nod.u]++; 85 if(cou[nod.u]==k)return nod.d; 86 for(i=0;i<G1[nod.u].size();i++){ 87 Edge& e=edge[G1[nod.u][i]]; 88 q.push((Node){nod.d-d[nod.u]+d[e.to]+e.dis,e.to}); 89 } 90 } 91 return 0; 92 } 93 94 int main() 95 { 96 // freopen("in.txt","r",stdin); 97 int i,ans,u,v,dis; 98 while(~scanf("%d%d",&n,&m)){ 99 init(n); 100 for(i=0;i<m;i++){ 101 scanf("%d%d%d",&u,&v,&dis); 102 G1[u].push_back(i); 103 edge1.push_back((Edge){u,v,dis}); 104 G2[v].push_back(i); 105 edge2.push_back((Edge){v,u,dis}); 106 } 107 scanf("%d%d%d",&S,&T,&K); 108 if(m){ 109 dijkstra(T,edge2); 110 if(d[S]!=INF) 111 printf("%d\n",astar(S,T,K,edge1)); 112 else printf("-1\n"); 113 } 114 else printf("-1\n"); 115 } 116 return 0; 117 }