POJ2449Remmarguts' Date

题意:求K短路

先介绍A*算法:

A*算法是一种启发式的搜索,不是纯粹的盲目式搜索,A*算法中有个估价算法g(n),对于每个点而言,都有一个g(n)和h(n)来确定的f(n),实际上就是以f(n)为参考权值来确定搜索的方向,在这里,我们的h(n)表示的是从s点出发到n这个点现在走过的路径长度,而g(n)表示的是从n到e的最短长度的大小,那么就确定了搜索的优先性,这里的A*算法的估价函数g(n)是完美估价,搜索的方向一定是对的。

分析:K短路可以用A*+spfa求。。先求出终点到各个点的最短距离d[1~n],这个变是A*算法的估价函数d[1~n];

建图的时候建一个正向的一个反向的,反向图用来求估价终点到每个点的距离,即为搜索的估价函数。

注意:若s==t,则k++, 因为题目要求必须走过路径。

View Code
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define MAXN 1005
#define INF 1000000000
using namespace std;
int n,m,e;
struct eee{
    int v;//正向图的终止点
    int u;//反向图的终止点
    int next;//正向图的下一条边
    int next1;//反向图的下一条边
    int w;//权值
}edge[100*MAXN];

struct node{
    int v;
    int f;
    int g;
    bool operator <(const node &a)const{
        if(f==a.f)return g>a.g;
        else return f>a.f;
    }
};
int d[MAXN];//d[v]表示的是终点到v的距离,即估价函数g
int first[MAXN],first1[MAXN],vis[MAXN];
priority_queue<node>pq;
queue<int> que;
void add(int u,int v,int w){
    edge[e].u=u;
    edge[e].w=w;
    edge[e].v=v;
    edge[e].next=first[u];
    first[u]=e;
    edge[e].next1=first1[v];
    first1[v]=e++;
}
void init(int n){
    memset(first,-1,sizeof(first));
    memset(vis,0,sizeof(vis));
    memset(first1,-1,sizeof(first1));
    e=0;
}
void spfa(int s){//求估价函数
    while(!que.empty())que.pop();
    for(int i=1;i<=n;i++)d[i]=INF;
    d[s]=0;vis[s]=1;
    que.push(s);
    while(!que.empty()){
        int u=que.front();
        que.pop();
        vis[u]=0;
        for(int i=first1[u];i!=-1;i=edge[i].next1){
            int v=edge[i].u;
            if(d[v]>d[u]+edge[i].w){
                d[v]=d[u]+edge[i].w;
                if(!vis[v]){
                    que.push(v);
                    vis[v]=1;
                }
            }
        }
    }
}
int a_start(int s,int t,int k){
    while(!pq.empty())pq.pop();
    int cnt=0;
    if(s==t)k++;
    node a;
    a.v=s,a.g=0;
    a.f=a.g+d[s];
    pq.push(a);
    while(!pq.empty()){
        node b=pq.top();
        pq.pop();
        if(b.v==t)cnt++;
        if(cnt==k)return b.g;
        for(int i=first[b.v];i!=-1;i=edge[i].next){
            int v=edge[i].v;
            a.g=b.g+edge[i].w;
            a.f=a.g+d[v];
            a.v=v;
            pq.push(a);
        }
    }
    return -1;
}
int main()
{
    while(scanf("%d%d",&n,&m)==2){
        init(n);
        int a,b,c;
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,c);
        }
        int s,t,k;
        scanf("%d%d%d",&s,&t,&k);
        spfa(t);
        if(d[s]==INF)printf("-1\n");
        else
        printf("%d\n",a_start(s,t,k));
    }
    return 0;
}
原文地址:https://www.cnblogs.com/arbitrary/p/2682402.html