标签:cout field single strong back 处理 enter open clu
Time Limit: 4000MS | Memory Limit: 65536K | |
Total Submissions: 29625 | Accepted: 8034 |
Description
Input
Output
Sample Input
2 2 1 2 5 2 1 4 1 2 2
Sample Output
14
Source
/*
*算法思想:
*单源点最短路径+高级搜索A*;
*A*算法结合了启发式方法和形式化方法;
*启发式方法通过充分利用图给出的信息来动态地做出决定而使搜索次数大大降低;
*形式化方法不利用图给出的信息,而仅通过数学的形式分析;
*
*算法通过一个估价函数f(h)来估计图中的当前点p到终点的距离,并由此决定它的搜索方向;
*当这条路径失败时,它会尝试其他路径;
*对于A*,估价函数=当前值+当前位置到终点的距离,即f(p)=g(p)+h(p),每次扩展估价函数值最小的一个;
*
*对于K短路算法来说,g(p)为当前从s到p所走的路径的长度;h(p)为点p到t的最短路的长度;
*f(p)的意义为从s按照当前路径走到p后再走到终点t一共至少要走多远;
*
*为了加速计算,h(p)需要在A*搜索之前进行预处理,只要将原图的所有边反向,再从终点t做一次单源点最短路径就能得到每个点的h(p)了;
*
*算法步骤:
*(1)将有向图转置即所有边反向,以原终点t为源点,求解t到所有点的最短距离;
*(2)新建一个优先队列,将源点s加入到队列中;
*(3)从优先级队列中弹出f(p)最小的点p,如果点p就是t,则计算t出队的次数;
*如果当前为t的第k次出队,则当前路径的长度就是s到t的第k短路的长度,算法结束;
*否则遍历与p相连的所有的边,将扩展出的到p的邻接点信息加入到优先级队列;
代码:
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<map> #include<queue> #include<stack> #include<vector> using namespace std; typedef long long ll; const int maxn=1e5+100,inf=0x3f3f3f3f,mod=1e9+7; const ll INF=1e13+100; struct node { int to,w; bool operator <(const node &x)const { return w>x.w; } }; map<int,vector<node> >G; map<int,vector<node> >T; int dist[maxn]; priority_queue<node>q; void dij(int n,int s) { for(int i=1; i<=n; i++) dist[i]=inf; node e,ne; e.to=s,e.w=dist[s]=0; q.push(e); while(!q.empty()) { e=q.top(); q.pop(); for(int i=0; i<T[e.to].size(); i++) { ne=T[e.to][i]; if(dist[ne.to]>dist[e.to]+ne.w) { ne.w=dist[ne.to]=dist[e.to]+ne.w; q.push(ne); } } } } struct node2 { int to; //g(p)为当前从s到p所走的路径的长度;h(p)为点p到t的最短路的长度; int g,f;//f=g+h,f(p)的意义为从s按照当前路径走到p后再走到终点t一共至少要走多远; bool operator<(const node2 &x ) const { if(x.f==f) return x.g<g; return x.f<f; } }; int A_star(int s,int t,int k,int n) { if(dist[s]==inf) return -1; priority_queue<node2>Q; if(s==t) k++; int cnt=0; node2 e,ne; e.to=s,e.g=0,e.f=e.g+dist[e.to]; Q.push(e); while(!Q.empty()) { e=Q.top(); Q.pop(); if(e.to==t) cnt++; //找到一条最短路径 if(cnt==k) return e.g; //找到k短路 for(int i=0; i<G[e.to].size(); i++) { ne.to=G[e.to][i].to; ne.g=e.g+G[e.to][i].w; ne.f=ne.g+dist[ne.to]; Q.push(ne); } } return -1; } int main() { int n,m; scanf("%d%d",&n,&m); for(int i=1; i<=m; i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); node e; e.to=v,e.w=w; G[u].push_back(e); e.to=u,T[v].push_back(e); } int s,t,k; scanf("%d%d%d",&s,&t,&k); dij(n,t); cout<<A_star(s,t,k,n)<<endl; return 0; }
标签:cout field single strong back 处理 enter open clu
原文地址:http://www.cnblogs.com/GeekZRF/p/6841484.html