题意:求n个点中,a到b的第k条最短路
思路:
用最短路求出估价函数的h,再在搜索过程中记录g,利用A*求出
最开始想到的便是A*和最短路,但是脑子抽了,居然一个一个去求- -,TL了后才发现可以倒着求最短路一次搞定。
但是又发现没考虑重边的问题,又换了种姿势终于AC,感觉太习惯于直接开二维数组,这不行啊- -
当from = to时,因为还没出发就已经判定k--,所以在其相等时,k+=1
问题:
1.对算法的理解不够透彻- -
2.在题目上考虑不够全面,导致不得不重写代码
#include <iostream> #include <cstdio> #include <vector> #include <queue> #include <cstring> #include <functional> using namespace std; const int INF = 0x3f3f3f3f; typedef long long ll; int vis[1005]; int low[1005]; int head[1005],head1[1005]; int from,to; int tot; int n,m,k; struct edge { int u,v; int len; int next; //正向 int next1; //反向 edge() {} edge(int x,int y,int c):u(x),v(y),len(c) {} }; edge p[100005]; struct node { int po; int g,h; node() {} node(int x,int y,int z):po(x),g(y),h(z) {} bool operator<(const node& a)const { return g+h>a.g+a.h; } }; void add_edge(int u,int v,int c) { p[tot] = edge(u,v,c); p[tot].next = head[u]; head[u] = tot; p[tot].next1 = head1[v]; head1[v] = tot++; } void work(int c) //从to开始找出所有点到to的最短路 { priority_queue<node>que; memset(vis,0,sizeof(vis)); for(int i = 1; i <= n; i++) low[i] = INF; low[c] = 0; que.push(node(c,0,0)); while(!que.empty()) { node cur = que.top(); que.pop(); if(vis[cur.po]) continue; vis[cur.po] = 1; for(int i = head1[cur.po]; ~i; i = p[i].next1) //反向查找 { if(low[p[i].u] > low[cur.po]+p[i].len) { low[p[i].u] = low[cur.po] + p[i].len; que.push(node(p[i].u,0,low[p[i].u])); } } } } int bfs(int t) { int num = 0; priority_queue<node>que; node cur; cur.po = t; cur.g = 0; que.push(cur); while(!que.empty()) { cur = que.top(); que.pop(); int tp = cur.po; if(tp == to) { num ++; if(num == k) { return cur.g; } } for(int i = head[cur.po]; ~i; i = p[i].next) { node tmp; int x = p[i].v; tmp.po = x; tmp.g = cur.g + p[i].len; tmp.h = low[x]; que.push(tmp); } } return -1; } void ini() { tot = 0; memset(head,-1,sizeof(head)); memset(head1,-1,sizeof(head1)); } int main() { int a,b,len; while(scanf("%d%d",&n,&m) != EOF) { ini(); for(int i = 0; i < m; i++) { scanf("%d%d%d",&a,&b,&len); add_edge(a,b,len); } scanf("%d%d%d",&from,&to,&k); work(to); if(low[from] == INF) //如果from不能到达to { printf("-1 "); continue; } if(from == to) { k++; } printf("%d ",bfs(from)); } return 0; }