标签:
Time Limit: 4000MS | Memory Limit: 65536K | |
Total Submissions: 26355 | Accepted: 7170 |
Description
Input
Output
Sample Input
2 2 1 2 5 2 1 4 1 2 2
Sample Output
14
思路:利用A*算法求最短路。第一次搜到终点为最短路,第二次搜到终点为次短路...第k次搜到终点为k短路。A*算法的估价函数f(x)=g(x)+h(x)。g(x):从出发点到当前节点的距离。h(x):从当前节点到终点的距离。可构建反向边利用spfa求得。
#include <cstdio> #include <cstring> #include <queue> using namespace std; const int MAXN=1005; const int INF=0x3f3f3f3f; struct Edge{ int to,w,next; }es[100005],rves[100005]; int n,m; int src,tml,kth; int head[MAXN],tot; int rhead[MAXN],rtot; void addedge(int u,int v,int w) { es[tot].to=v; es[tot].w=w; es[tot].next=head[u]; head[u]=tot++; rves[rtot].to=u; rves[rtot].w=w; rves[rtot].next=rhead[v]; rhead[v]=rtot++; } int d[MAXN],vis[MAXN]; void spfa(int s)//利用反向边确定估价函数h(x):i到tml的距离 { for(int i=1;i<=n;i++) { d[i]=INF; vis[i]=0; } queue<int> que; que.push(s); d[s]=0; vis[s]=1; while(!que.empty()) { int u=que.front();que.pop(); vis[u]=0; for(int i=rhead[u];i!=-1;i=rves[i].next) { Edge e=rves[i]; if(d[e.to]>d[u]+e.w) { d[e.to]=d[u]+e.w; if(!vis[e.to]) { vis[e.to]=1; que.push(e.to); } } } } } struct Node{ int nod,g,h; Node(){} Node(int cnod,int cg,int ch):nod(cnod),g(cg),h(ch){} bool operator<(const Node &node) const { return g+h > node.g+node.h; } }; int astar(int s) { priority_queue<Node> que; que.push(Node(s,0,d[s]));//g(x):src到i的距离.h(x):i到tml的距离. while(!que.empty()) { Node now=que.top();que.pop(); int u=now.nod; if(u==tml) { kth--; if(kth==0) return now.g+now.h;//第k条最短路 } for(int i=head[u];i!=-1;i=es[i].next) { Edge e=es[i]; int g=now.g+e.w; int h=d[e.to]; que.push(Node(e.to,g,h)); } } return -1; } int main() { while(scanf("%d%d",&n,&m)!=EOF) { memset(head,-1,sizeof(head)); memset(rhead,-1,sizeof(rhead)); tot=0; rtot=0; for(int i=0;i<m;i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); addedge(u,v,w); } scanf("%d%d%d",&src,&tml,&kth); if(src==tml) kth++;//若src等于tml那么最短路为0,不算 spfa(tml); printf("%d\n",astar(src)); } return 0; }
标签:
原文地址:http://www.cnblogs.com/program-ccc/p/5638145.html