poj2449 Remmarguts' Date(K短路)(A*)

版权声明:本文为博主原创文章,未经博主允许不得转载,除非先点了赞。 https://blog.csdn.net/A_Bright_CH/article/details/81865312

题意

k短路

题解

A*+dijkstra
用最短路长度作为k短路的估价函数再适合不过了。恰好满足f[x]<=g[x](f是估价函数,g是实际情况)。
因为f应当是距离t的最短路,所以我们要反着跑一遍dijkstra,这样就处理好了f数组。
接下来正着跑A*。对于每个点可以的所有距离都记录下来,选择f[x]+d最小的优先遍历。
因为我们用的时优先BFS,当t第1次出队列时,一定是从s到该点的最短路径;第k次出队,则是从s到该点的k短路。
注意一个坑点:当s==t时,k++。

代码

#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1010,maxm=100010;

int n,m;
int s,t,k;
struct edge
{
    int x,y,c,next;
}e[maxm],fe[maxm];int len=0,last[maxn],flast[maxn];
void ins(int x,int y,int c)
{
    e[++len]=(edge){x,y,c,last[x]};last[x]=len;
    fe[len]=(edge){y,x,c,flast[y]};flast[y]=len;//debug len只要加一次 
}

int f[maxn];//f以最短路长作为估价函数 
struct F
{
    int x,d;
    bool operator<(F f1)const
    {
        return d>f1.d;
    }
};

bool v[maxn];
void dijkstra()
{
    priority_queue<F> q;
    q.push((F){t,0});
    memset(f,63,sizeof(f));f[t]=0;
    memset(v,false,sizeof(v));
    while(!q.empty())
    {
        F top=q.top();q.pop();
        int x=top.x,d=top.d;
        if(v[x]) continue;
        v[x]=true;
        for(int k=flast[x];k;k=fe[k].next)
        {
            int y=fe[k].y;
            if(f[y]>f[x]+fe[k].c)
            {
                f[y]=f[x]+fe[k].c;
                q.push((F){y,f[y]});
            }
        }
    }
}

struct R
{
    int x,d;//x表示点编号 d表示当前距离 
    bool operator<(R r1)const
    {
        return d+f[x]>r1.d+f[r1.x];
    }
};

void Astra()
{
    if(s==t) k++;//坑!!! 
    priority_queue<R> q;
    q.push((R){s,0});
    while(!q.empty())
    {
        R top=q.top();q.pop();
        int x=top.x,d=top.d;
        if(x==t)
            if(k==1)
            {
                printf("%d\n",d);
                return ;
            }    
            else
            {
                k--;
            }
        for(int k=last[x];k;k=e[k].next)
        {
            int y=e[k].y;
            int nd=d+e[k].c;
            q.push((R){y,nd});
        }
    }
    printf("-1\n");
}

int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        len=0;
        memset(last,0,sizeof(last));
        memset(flast,0,sizeof(flast));
        for(int i=1;i<=m;i++)
        {
            int x,y,c;
            scanf("%d%d%d",&x,&y,&c);
            ins(x,y,c);
        }
        scanf("%d%d%d",&s,&t,&k);
        dijkstra();
        Astra();
    }
    
    return 0;
}

猜你喜欢

转载自blog.csdn.net/A_Bright_CH/article/details/81865312