Time Limit: 4000MS | Memory Limit: 65536K | |
Total Submissions: 24007 | Accepted: 6535 |
Description
Input
Output
Sample Input
2 2 1 2 5 2 1 4 1 2 2
Sample Output
14
给一个图,求第k短路.
运用spfa反向求一次最短路,可以求得终点(反向后变成起点)到各点的最短路径,变成A*的估价函数,A*的方程为f(v) = g(v) + h(v),其中f为估价函数,g(v)为出发点到该点已经走的距离,h(v)为预处理的距离,也就是刚才spfa反向求得起点到各点的最短路值。
AC代码:
#include
#include
#include
#include
using namespace std;
const int maxe = 100000;
const int inf = 0x3f3f3f3f;
struct Node1
{
int to;
int g,f; // f = g + h;
bool operator < (const Node1 &r) const
{
if(r.f == f) return r.g < g;
return r.f < f;
}
};
int dist[maxe];
int head[maxe];
int ehead[maxe];
int outque[maxe];
struct Node
{
int to;
int w;
int next;
}edge[maxe*3],edge1[maxe*3];
int cnt1,cnt2;
void init()
{
cnt1 = 0;
cnt2 = 0;
memset(head,-1,sizeof(head));
memset(ehead,-1,sizeof(ehead));
}
void addEdge(int u,int v,int w)
{
edge[cnt1].to = v;
edge[cnt1].w = w;
edge[cnt1].next = head[u];
head[u] = cnt1++;
}
void add_Edge(int u,int v,int w)
{
edge1[cnt2].to = v;
edge1[cnt2].w = w;
edge1[cnt2].next = ehead[u];
ehead[u] = cnt2++;
}
bool SPFA(int s,int n)
{
int i,k;
bool vis[maxe];
int queue[maxe];
int iq;
int top;
for(i=0;i<=n;i++)
{
dist[i] = inf;
}
memset(vis,false,sizeof(vis));
memset(outque,0,sizeof(outque));
iq = 0;
queue[iq++] = s;
vis[s] = true;
dist[s] = 0;
i = 0;
while(i != iq)
{
top = queue[i];
vis[top] = false;
outque[top]++;
if(outque[top] > n) return false;
k = ehead[top];
while(k >= 0)
{
if(dist[edge1[k].to] - edge1[k].w > dist[top])
{
dist[edge1[k].to] = dist[top] + edge1[k].w;
if(!vis[edge1[k].to])
{
vis[edge1[k].to] = true;
queue[iq] = edge1[k].to;
iq++;
}
}
k = edge1[k].next;
}
i++;
}
return true;
}
int a_star(int start,int end,int n,int k)
{
Node1 e,ne;
int cnt = 0;
priority_queue que;
if(start == end) k++; //起点终点一样+1
if(dist[start] == inf)
{
return -1;
}
e.to = start;
e.g = 0;
e.f = e.g + dist[e.to];
que.push(e);
while(!que.empty())
{
e = que.top();
que.pop();
if(e.to == end)
{
cnt++;
}
if(cnt == k)
{
return e.g;
}
for(int i=head[e.to];i != -1;i = edge[i].next)
{
ne.to = edge[i].to;
ne.g = e.g + edge[i].w;
ne.f = ne.g + dist[ne.to];
que.push(ne);
}
}
return -1;
}
int main()
{
int m,n;
int i;
int a,b,time;
int st,ed,ki;
//freopen("1.txt","r",stdin);
while(scanf("%d%d",&m,&n) != EOF)
{
init();
for(i=1;i<=n;i++)
{
scanf("%d%d%d",&a,&b,&time);
addEdge(a,b,time);
add_Edge(b,a,time);
}
scanf("%d%d%d",&st,&ed,&ki);
SPFA(ed,m); //反向终点变成起点
printf("%d\n",a_star(st,ed,m,ki));
}
return 0;
}