K短路(A*+SPFA)
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstring> 5 #include<queue> 6 using namespace std; 7 const int MAX_V = 1100; 8 const int MAX_E = 110000; 9 const int INF = 0x3f3f3f3f; 10 11 struct ENode 12 { 13 int to; 14 int w; 15 int Next; 16 }; 17 ENode edegs[MAX_E]; 18 ENode edegs1[MAX_E]; //存反图; 19 int Head[MAX_V], Head1[MAX_V], tnt, tnt1; 20 void Add_ENode (int a, int b, int w) 21 { 22 ++ tnt; 23 edegs[tnt].to= b; 24 edegs[tnt].w= w; 25 edegs[tnt].Next= Head[a]; 26 Head[a]= tnt; 27 // ++ tnt; //无向图 28 // edegs[tnt].to= a; 29 // edegs[tnt].w= w; 30 // edegs[tnt].Next= Head[b]; 31 // Head[b]= tnt; 32 } 33 void Add_ENode1 (int a, int b, int w) 34 { 35 /**建反向图*/ 36 ++ tnt1; 37 edegs1[tnt1].to= b; 38 edegs1[tnt1].w= w; 39 edegs1[tnt1].Next= Head1[a]; 40 Head1[a]= tnt1; 41 // ++ tnt1; //无向图 42 // edegs1[tnt1].to= a; 43 // edegs1[tnt1].w= w; 44 // edegs1[tnt1].Next= Head1[b]; 45 // Head1[b]= tnt1; 46 } 47 48 int Dis[MAX_V]; 49 bool visit[MAX_V]; //是否已经遍历过; 50 int que[MAX_V]; // 模拟队列; 51 int outque[MAX_V]; //记录每个点出队列的次数,防止有负边,保证无负边的图可以省略; 52 bool SPFA(int s, int n) 53 { 54 /**SPFA处理反向图,预处理出Dis[]*/ 55 /*s:起点; n:点的总数*/ 56 int iq; //队列中元素个数; 57 memset(Dis, INF, sizeof(Dis)); 58 memset(visit, false, sizeof(visit)); 59 memset(outque, 0, sizeof(outque)); 60 iq= 0; 61 que[iq ++]= s; 62 visit[s]= true; 63 Dis[s]= 0; 64 int i= 0; 65 while (i< iq) 66 { 67 int u= que[i]; 68 visit[u]= false; 69 outque[u] ++; 70 if (outque[u]> n) return false; //当一个点进出队列超过n 次,必然有负边存在; 71 72 for (int k= Head1[u]; k!= -1; k= edegs1[k].Next) 73 { 74 /*bfs,和Dijkstra相似*/ 75 int v= edegs1[k].to; 76 if (Dis[v]> Dis[u]+ edegs1[k].w) 77 { 78 Dis[v]= Dis[u]+ edegs1[k].w; 79 if (! visit[v]) 80 { 81 visit[v]= true; 82 que[iq ++]= v; 83 } 84 } 85 } 86 i ++; 87 } 88 return true; 89 } 90 91 struct Node 92 { 93 int from; 94 int g; //g表示到当前点的路径长度 95 int f; //f=g+dis dis表示当前点到终点的最短路径,即之前的预处理 96 bool operator < (const Node &r) const 97 { 98 if (r.f== f) return r.g- g< 0; 99 return r.f- f< 0; 100 } 101 }; 102 int A_star (int s, int t, int n, int k) 103 { 104 Node e, ne; 105 int cnt= 0; 106 priority_queue<Node> que; 107 if (s== t) k ++; 108 if (Dis[s]== INF) return -1; 109 e.from= s; 110 e.g= 0; 111 e.f= e.g+ Dis[e.from]; 112 que.push(e); 113 while (! que.empty()) 114 { 115 e= que.top(); 116 que.pop(); 117 if (e.from== t) cnt ++; 118 if (cnt== k) return e.g; 119 for (int i= Head[e.from]; i!= -1; i= edegs[i].Next) 120 { 121 ne.from= edegs[i].to; 122 ne.g= e.g+ edegs[i].w; 123 ne.f= ne.g+ Dis[ne.from]; 124 que.push(ne); 125 } 126 } 127 return -1; 128 } 129 130 void into() 131 { 132 /**初始化*/ 133 memset(Head,-1,sizeof(Head)); 134 memset(Head1,-1,sizeof(Head1)); 135 tnt= -1; tnt1= -1; 136 } 137 138 int main() 139 { 140 int n, m, k; 141 int a, b, w; 142 while (~ scanf("%d %d %d", &n, &m, &k)) 143 { 144 into(); 145 for (int i= 0; i< m; i ++) 146 { 147 scanf("%d %d %d", &a, &b, &w); 148 Add_ENode(a, b, w); 149 Add_ENode1(b, a, w); //建反图 150 } 151 SPFA(n, n); //处理出从终点到其他点的最短路径距离; 152 int far= A_star(1, n, n, k); 153 printf("%d\n", far); 154 } 155 return 0; 156 }