A*算法(k短路)模板 poj 2449

a*算法就是在bfs扩展的时候优化了一下,对于一个点x,当前花费a,到终点花费h[x],那a+h[x]就可以视作它这个点的总花费,这就可以在bfs时优先遍历花费少的点

#include<algorithm>
#include<vector>
#include<queue>
#include<string.h>
using namespace std;
#define ll long long
#include<stdio.h>
#define maxn 205000
#define mod 100003
vector<pair<int,int> >e[maxn];
vector<pair<int,int> >e1[maxn];
int h[maxn];
struct node
{
    int d,id;
    friend bool operator <(node a,node b)
    {
        return h[a.id]+a.d>h[b.id]+b.d;
    }
};
priority_queue<node>q;
struct node1
{
    int d,id;
    friend bool operator <(node1 a,node1 b)
    {
        return a.d>b.d;
    }
};
priority_queue<node1>q1;
int vis1[maxn];
void dijk(int st)
{
    memset(h,0x3f,sizeof(h));
    h[st]=0;
    q1.push(node1{0,st});
    while(!q1.empty())
    {
        int u=q1.top().id;
        q1.pop();
        //printf("u=%d\n",u);
        if(vis1[u]==1) continue;
        vis1[u]=1;
        //printf("1111\n");
        for(int i=0;i<e1[u].size();i++)
        {
            //printf("3333\n");
            int v=e1[u][i].first,w=e1[u][i].second;
            //printf("----\n");
            //printf("v=%d\n",v);
            if(h[u]+w<h[v])
            {
                h[v]=h[u]+w;
                //printf(" v=%d\n",v);
                if(vis1[v]==0)q1.push(node1{h[v],v});
            }
        }
    }
    //printf("222\n");
}
int ans[maxn];
void slove(int s,int t,int k)
{
    int p=0;
    q.push(node{0,s});
    memset(ans,-1,sizeof(ans));
    while(!q.empty()&&p<k)
    {
        int u=q.top().id,d=q.top().d;
        q.pop();
        //printf("u=%d d=%d\n",u,d);
        if(u==t) ans[++p]=d;
        for(int i=0;i<e[u].size();i++)
        {
            int v=e[u][i].first,w=e[u][i].second;
            if(h[u]==h[maxn-1]) continue;
            //if(v==t) ans[++p]=d+w;
            //printf(" v=%d w=%d p=%d\n",v,w,p);
            q.push(node{d+w,v});
        }
    }
    printf("%d\n",ans[k]);
}
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);
        e[u].push_back({v,w});
        e1[v].push_back({u,w});
    }
    int s,t,k;
    scanf("%d %d %d",&s,&t,&k);
    dijk(t);
    if(s==t) k++;
    //for(int i=1;i<=n;i++) printf("h[%d]=%d\n",i,h[i]);
    slove(s,t,k);
}

猜你喜欢

转载自blog.csdn.net/qq_43497140/article/details/107753911
今日推荐