POJ 2449 Remmarguts' Date(k短路模板)

link:https://vjudge.net/problem/POJ-2449

前面输入与大多最短路题相同

最后一行输入s,t,k 求从s到t的第K短路

wiki link: https://en.wikipedia.org/wiki/A*_search_algorithm

出题者的算法是首先计算任意一点到终点的最短距离,使用这个距离作为A*算法中H函数(从当前点到终点的估计函数)使用A*算法。跟一般的A*算法不同的是,一个结点可以被多次扩展到(A*算法中只保留到达一个结点的最短路径)。使用这个算法就可以得到起点到终点的最短路径,第二短路径,第三短路径……

复杂度很难算清楚,但是非常低。

#include <iostream>
#include <cstring>
#include <queue>

using namespace std;

const int MAXN=1010;

struct node
{
     int p,g,h;
     bool operator < (node a) const
     {
          return a.g+a.h<g+h;
     }
};

struct node1
{
     int x,y,w,next;
}line[MAXN*100],line1[MAXN*100];

int n,m,i,link[MAXN],link1[MAXN],g[MAXN],s,e,k;
bool used[MAXN];
priority_queue<node> myqueue;

void djikstra()
{
     int i,k,p;
     memset(used,0,sizeof(used));
     memset(g,0x7F,sizeof(g));
     g[e]=0;
     for (p=1;p<=n;p++)
     {
          k=0;
          for (i=1;i<=n;i++)
            if (!used[i] && (!k || g[i]<g[k]))
              k=i;
          used[k]=true;
          k=link1[k];
          while (k)
          {
               if (g[line1[k].y]>g[line1[k].x]+line1[k].w)
                   g[line1[k].y]=g[line1[k].x]+line1[k].w;
               k=line1[k].next;
          }
     }
     return ;
}

int Astar()
{
    int t,times[MAXN];
    node h,temp;
    while(!myqueue.empty()) myqueue.pop();
    memset(times,0,sizeof(times));
    h.p=s;h.g=0;h.h=0;myqueue.push(h);
    while(!myqueue.empty())
    {
        h=myqueue.top();
        myqueue.pop();
        times[h.p]++;
        if(times[h.p]==k&&h.p==e) return h.h+h.g;
        if(times[h.p]>k) continue;
        t=link[h.p];
        while(t)
        {
            temp.h=h.h+line[t].w;
            temp.g=g[line[t].y];
            temp.p=line[t].y;
            myqueue.push(temp);
            t=line[t].next;
        }
    }
    return -1;

}

int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>m;

    memset(link,0,sizeof(link));
    memset(link1,0,sizeof(link1));

    for(int i=1;i<=m;i++)
    {
        cin>>line[i].x>>line[i].y>>line[i].w;
        line[i].next=link[line[i].x]; link[line[i].x]=i;
        line1[i].x=line[i].y; line1[i].y=line[i].x; line1[i].w=line[i].w;
        line1[i].next=link1[line1[i].x]; link1[line1[i].x]=i;
    }
    cin>>s>>e>>k;
    if(s==e) k++;
    djikstra();
    cout<<Astar()<<endl;
    
    return 0;
}

 

posted @ 2018-08-10 20:49  Somnus、M  阅读(214)  评论(0编辑  收藏  举报