POJ 3635 优先队列BFS

这里写图片描述
(感谢lyd学长的幻灯片)
注意vis数组的应用 在vis[i][j]中 i表示到了第i个点 j表示还剩j升油 vis[i][j]表示最小话费。 这样只需搜到话费比它少的更新入堆就OK了

//By: Sirius_Ren
#include <queue>
#include <cstdio>
#include <cstring>
using namespace std;
struct node{int num,wei,oil;}jy,temp;
int next[20005],first[20005],v[20005],w[20005],p[20005],tot=0,c,s,e,ans,vis[2005][205];
void add(int x,int y,int ww){v[tot]=y,w[tot]=ww,next[tot]=first[x],first[x]=tot++;}
bool operator<(node a,node b){return a.wei>b.wei;}
bool bfs(){
    priority_queue<node>pq;
    memset(vis,0x3f,sizeof(vis));
    jy.num=s;jy.oil=jy.wei=0;vis[jy.num][jy.oil]=0;
    pq.push(jy);
    while(!pq.empty()){
        jy=pq.top(),pq.pop();
        if(jy.num==e){printf("%d\n",jy.wei);return true;}
        temp.num=jy.num,temp.oil=jy.oil+1,temp.wei=jy.wei+p[jy.num];
        if(temp.oil<=c&&vis[temp.num][temp.oil]>temp.wei+p[jy.num])vis[temp.num][temp.oil]=temp.wei,pq.push(temp);
        for(int i=first[jy.num];~i;i=next[i])
            if(jy.oil-w[i]>=0&&vis[v[i]][jy.oil-w[i]]>jy.wei)
                temp.num=v[i],temp.oil=jy.oil-w[i],temp.wei=jy.wei,vis[temp.num][temp.oil]=temp.wei,pq.push(temp);
    }
    return false;
}
int main(){
    int n,m,xx,yy,ww,q;
    scanf("%d%d",&n,&m);
    memset(first,-1,sizeof(first));
    for(int i=0;i<n;i++) scanf("%d",&p[i]);
    for(int i=1;i<=m;i++)scanf("%d%d%d",&xx,&yy,&ww),add(xx,yy,ww),add(yy,xx,ww);
    scanf("%d",&q);
    while(q--){
        scanf("%d%d%d",&c,&s,&e);
        if(!bfs())printf("impossible\n");
    }
}

这里写图片描述

转载于:https://www.cnblogs.com/SiriusRen/p/6532446.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值