A*——第K短路

 

#include <cstring>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>

using namespace std;

const int INF=1e9;

struct node
{
    int to,w,next;
}edge1[500010];

node edge2[500010];

struct A
{
    int f,g,v;
    bool operator <(const A a)const
    {
        if(a.f==f)
            return a.g<g;
        return a.f<f;
    }
};

int head1[1010];
int head2[1010];
bool vis[1010];
int dis[1010];
int tol;
int n,m,k;

void addEdge(int u,int v,int w)
{
    edge1[tol].to=v;
    edge1[tol].w=w;
    edge1[tol].next=head1[u];
    head1[u]=tol;
    edge2[tol].to=u;
    edge2[tol].w=w;
    edge2[tol].next=head2[v];
    head2[v]=tol;
    tol++;
}

void init()
{
    tol=0;
    memset(head1,-1,sizeof(head1));
    memset(head2,-1,sizeof(head2));
}

void spfa(int des)
{
    memset(vis,false,sizeof(vis));
    for(int i=1;i<=n;i++)
        dis[i]=INF;
    dis[des]=0;
    queue<int>q;
    vis[des]=true;
    q.push(des);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        vis[u]=false;
        for(int i=head2[u];i!=-1;i=edge2[i].next)
        {
            int v=edge2[i].to;
            if(dis[v]>dis[u]+edge2[i].w)
            {
                dis[v]=dis[u]+edge2[i].w;
                if(!vis[v])
                {
                    vis[v]=true;
                    q.push(v);
                }
            }
        }
    }
}

int Astar(int src,int des)
{
    int cnt=0;
    if(src==des)
        k++;
    if(dis[src]==INF)
        return -1;
    priority_queue<A>q;
    A a;
    a.v=src;
    a.g=0;
    a.f=dis[src];
    q.push(a);
    while(!q.empty())
    {
        A a=q.top();
        q.pop();
        if(a.v==des)
        {
            cnt++;
            if(cnt==k)
            {
                return a.g;
            }
        }
        for(int i=head1[a.v];i!=-1;i=edge1[i].next)
        {
            A t;
            t.g=a.g+edge1[i].w;
            t.v=edge1[i].to;
            t.f=t.g+dis[t.v];
            q.push(t);
        }
    }
    return -1;
}

int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        init();
        int u,v,w;
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            addEdge(u,v,w);
        }
        int src,des;
        scanf("%d%d%d",&src,&des,&k);
        spfa(des);
        cout<<Astar(src,des)<<endl;
    }
    return 0;
}

 

posted @ 2016-08-08 14:22  相儒以沫  阅读(188)  评论(0编辑  收藏  举报