• 《算法竞赛进阶指南》0x26广搜变形 POJ3635


    题目链接:http://poj.org/problem?id=3635

    题目和最短路算法的形式很像,只要对每个状态确定转移的分支即可,其中每次油量只加一,因为后续一定会在队列中被取出来重新加一(如果可以的话)

    代码:

    #include<iostream>
    #include<cstring>
    #include<queue>
    using namespace std;
    #define maxn 1005
    int head[maxn],nxt[maxn*20+10],ver[maxn*20+10],len[maxn*20+10];
    int d[maxn][105];
    int n,m,q;
    bool vis[maxn][105];
    int price[maxn];
    int tot=0;
    struct node{
        int dist,city,fuel;
        bool operator < (const node &a)const{
            return dist>a.dist;
        }
        node(){}
        node(int d,int c,int f):dist(d),city(c),fuel(f){}
    };
    void addedge(int u,int v,int w){
        ver[++tot]=v;
        len[tot]=w;
        nxt[tot]=head[u];
        head[u]=tot;
    }
    int bfs(int start ,int end,int cab){
        priority_queue<node> q;
        memset(d,0x3f,sizeof(d));
        memset(vis,false,sizeof(vis));
        q.push(node(0,start,0));
        
        while(!q.empty()){
            node cur=q.top();
            q.pop();
            if(cur.city == end)return cur.dist;//第一次出队一定是到达终点的最小花费 
            int city=cur.city,fuel=cur.fuel,dist=cur.dist;
            
            if(vis[city][fuel])continue;
            vis[city][fuel]=1;
            if(fuel+1<=cab && d[city][fuel+1]>dist+price[city]){
                d[city][fuel+1]=dist+price[city];
                q.push(node(d[city][fuel+1],city,fuel+1));
            }
            for(int i=head[city];i;i=nxt[i]){
                int to=ver[i],length=len[i];
                if(length <= fuel){
                    if(d[to][fuel-length] > dist)
                    {
                        d[to][fuel-length]=dist;
                        q.push(node(dist,to,fuel-length));
                    }
                }
            }
        }
        return -1; 
    }
    int main(){
        cin>>n>>m;
        for(int i=0;i<n;i++)scanf("%d",&price[i]);
        
        int u,v, w;
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&u,&v,&w);
            addedge(u,v,w);
            addedge(v,u,w);
        }
        
        cin>>q;
        int st,ed,ca;
        while(q--){
            scanf("%d%d%d",&ca,&st,&ed);
            int ans=bfs(st,ed,ca);
            if(ans==-1)cout<<"impossible"<<endl;
            else cout<<ans<<endl;
        }
        return 0;
    }
  • 相关阅读:
    数学笔记目录
    机器学习笔记目录
    物理学笔记目录
    二阶递推公式的通项公式
    分析Analysis 笔记
    从傅里叶变换到小波变换
    电动力学 期末复习
    电动力学 期中复习
    热学 期中复习
    理论力学第一章 Lagrange方程
  • 原文地址:https://www.cnblogs.com/randy-lo/p/13170011.html
Copyright © 2020-2023  润新知