poj2449Remmarguts' Date

题目:http://poj.org/problem?id=2449
A*算法详解:https://blog.csdn.net/z_mendez/article/details/47057461
f(n)=g(n)+h(n)
其中f(n)是每个可能试探点的估值,它有两部分组成:一部分为g(n),它表示从起始搜索点到当前点的代价(通常用某结点在搜索树中的深度来表示)。另一部分,即h(n),它表示启发式搜索中最为重要的一部分,即当前结点到目标结点的估值,h(n)设计的好坏,直接影响着具有此种启发式函数的启发式算法的是否能称为A*算法。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
#define len 100005
#define inf 0xffffff
using namespace std;
struct node
{
    int j,v,next;
}s[len],res[len];
struct ans
{
    int f,g,h;
    bool operator<(const ans &b)
    const{
        if(b.f==f) return b.g<g;
        else return b.f<f;
    }
};
int d[1010],head1[1010],head2[1010];
int k1,k2,S,T,K,sum,m,n;
bool vis[1010];
void add(int x,int y,int z)
{
    s[k1].j=y;
    s[k1].v=z;
    s[k1].next=head1[x];
    head1[x]=k1++;
    res[k2].j=x;
    res[k2].v=z;
    res[k2].next=head2[y];
    head2[y]=k2++;
}
void spfa(int x)
{
    d[x]=0;
    vis[x]=1;
    queue<int> q;
    q.push(x);
    while(!q.empty())
    {
        int t=q.front();
        q.pop();
        vis[t]=0;
        for(int i=head2[t];i!=-1;i=res[i].next)
        {
            int j=res[i].j;
            int v=res[i].v;
            if(d[j]>d[t]+v)
            {
                d[j]=d[t]+v;
                if(!vis[j]) q.push(j),vis[j]=1;
            }
        }
    }
}
int A_star(int x,int y)
{
    ans t;
    if(x==y) K++;
    if(d[x]==inf) return -1;
    t.h=x;
    t.g=0;
    t.f=t.g+d[x];
    priority_queue<ans> Q;
    Q.push(t);
    while(!Q.empty())
    {
        ans temp=Q.top();
        Q.pop();
        if(temp.h==y) sum++;
        if(sum==K) return temp.g;
        for(int i=head1[temp.h];i!=-1;i=s[i].next)
        {
            ans t;
            t.h=s[i].j;
            t.g=temp.g+s[i].v;
            t.f=t.g+d[t.h];
            Q.push(t);
        }
    }
    return -1;
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        int x,y,z;
        sum=0;
        k1=k2=1;
        for(int i=1;i<=n;i++) 
        {
            head1[i]=head2[i]=-1;
            vis[i]=0;
            d[i]=inf;
        }
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
        }
        scanf("%d%d%d",&S,&T,&K);
        spfa(T);
        printf("%d\n",A_star(S,T)); 
    }   
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值