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");
    }
}

这里写图片描述

posted @ 2016-06-06 16:09  SiriusRen  阅读(191)  评论(0编辑  收藏  举报