BZOJ 1975 [Sdoi2010]魔法猪学院

A*

我校神犇说用A*来找K短路最坏复杂度O(km)

#include<cstdio>
#define N 5005
#define M 200005
using namespace std;
struct edge{int next, to; double val;}e[M<<1];
struct node{int id; double g, h;}heap[2000000];
int ecnt=1, ans=0, last1[N], last2[N], q[N], tot=0, n, m;
double dis[N], limit;
const double INF = 100000000000.0;
bool vis[N];
void add(int a, int b, double c)
{
    e[++ecnt]=(edge){last1[a],b,c};
    last1[a]=ecnt;
    e[++ecnt]=(edge){last2[b],a,c};
    last2[b]=ecnt;
}
void check(int &i){if(i==N)i=0;}
void SPFA(int beg)
{
    for(int i = 1; i <= n; i++)
        dis[i]=INF;
    dis[beg]=0;
    q[0]=beg;
    for(int head=0, tail=1; head!=tail; head++)
    {
        check(head);
        int x=q[head];
        vis[x]=0;
        for(int i = last2[x]; i; i=e[i].next)
        {
            int y=e[i].to;
            if(dis[x]+e[i].val<dis[y])
            {
                dis[y]=dis[x]+e[i].val;
                if(!vis[y])
                {
                    vis[y]=1;
                    q[tail++]=y;
                    check(tail);
                }
            }
        }
    }
}
void heap_add(node x)
{
    heap[++tot]=x;
    for(int i = tot, j = i>>1; j; i=j, j>>=1)
    {
        if(heap[j].g+heap[j].h > heap[i].g+heap[i].h)
        {
            node t=heap[j];
            heap[j]=heap[i];
            heap[i]=t;
        }
        else break;
    }
}
void heap_pop()
{
    heap[1]=heap[tot--];
    for(int i = 1, j = i<<1; j <=tot; i=j, j<<=1)
    {
        if(j<tot && heap[j].g+heap[j].h>heap[j|1].g+heap[j|1].h)j|=1;
        if(heap[j].g+heap[j].h < heap[i].g+heap[i].h)
        {
            node t=heap[j];
            heap[j]=heap[i];
            heap[i]=t;
        }
        else break;
    }
}
void A_star(int beg)
{
    heap_add((node){beg,0,dis[beg]});
    while(tot)
    {
        node now=heap[1];
        heap_pop();
        if(now.id==n)
        {
            limit-=now.g;
            if(limit<0)
                break;
            ans++;
        }
        for(int i = last1[now.id]; i; i=e[i].next)
        {
            int y=e[i].to;
            heap_add((node){y, now.g+e[i].val, dis[y]});
        }
    }
}
int main()
{
    scanf("%d%d%lf",&n,&m,&limit);
    for(int i = 1; i <= m; i++)
    {
        int a, b;
        double c;
        scanf("%d%d%lf",&a,&b,&c);
        add(a,b,c);
    }
    SPFA(n);
    A_star(1);
    printf("%d\n",ans);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值