zoukankan      html  css  js  c++  java
  • POJ 3635 Full Tank? (最短路变形,BFS+优先队列)

    【题意】 给你 n 个点,m 条边,每走 1 单位的路径都会花费 1 单位的 fuel ,并且不同的点灌油的油的价格是不同的,现在给你一些询问,每一个询问给你起点、终点以及油箱的容量,问你所需要的最少的花费可以从起点到达终点。   涉及两个维的图最短路,一个是费用,一个是地点。(比如在位置0有1升油是一个点,在位置0有2升油又是另外一个点) 如果把这个点抽象出来,把费用看过边,那么最少费用就可以类似dijsktra算法那样不断的加入点。 于是得到一个扩展结点的策略: 1.每一次加一升油(因为题目的条件这些都是整数,所以可以类似离散化处理,一点一点加入油) 2.如果加的油足够走到下一个结点,那就走到下一个结点吧(记得减去路上消耗的油,还有花费不变...) (至于在第二次扩展时要不要加油,这个就不需要了.因为在第一种情况扩展结点的时候加油了...) 这里的BFS是把所有可扩展的节点都加入优先队列中,而Dijkstra是每次松弛了的点才加入,中间少了很多状态。但是思想都是一样的。不知道这题能不能像Dij那样做。  
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #define MID(x,y) ((x+y)>>1)
    #define mem(a,b) memset(a,b,sizeof(a))
    using namespace std;
    
    struct node{
        int u, v, w;
        int next;
    }edge[20003];
    struct Status{
        int u, fuel, cost;
        friend bool operator < (const Status n1, const Status n2){
            return n2.cost < n1.cost;
        }
    };
    int head[1003], cnt;
    int n, m;
    int price[1003];
    void init(){
        mem(head, -1);
        cnt = 0;
    }
    void add(int u, int v, int w){
        edge[cnt].u = u;
        edge[cnt].v = v;
        edge[cnt].w = w;
        edge[cnt].next = head[u];
        head[u] = cnt ++;
        return ;
    }
    priority_queue  > PQ;
    bool vis[1003][103];
    void push_PQ(int u, int f, int c){
        Status tmp;
        tmp.u = u;
        tmp.fuel = f;
        tmp.cost = c;
        PQ.push(tmp);
    }
    int BFS(int c, int s, int e){
        mem(vis, 0);
        while(!PQ.empty()){
            PQ.pop();
        }
        push_PQ(s, 0, 0);
        while(!PQ.empty()){
            Status tmp = PQ.top();
            PQ.pop();
            int u = tmp.u, fuel = tmp.fuel, cost = tmp.cost;
            vis[u][fuel] = 1;
            if (u == e){
                return cost;
            }
            // we choose to add a unit fuel;
            if (fuel < c && !vis[u][fuel+1]){
                push_PQ(u, fuel+1, cost+price[u]);
            }
            // we choose to go to the next node;
            for (int i = head[u]; i != -1; i = edge[i].next){
                if (fuel >= edge[i].w && !vis[edge[i].v][fuel-edge[i].w]){
                    push_PQ(edge[i].v, fuel-edge[i].w, cost);
                }
            }
        }
        return -1;
    }
    int main(){
        init();
        scanf("%d %d", &n, &m);
        for (int i = 0; i < n; i ++){
            scanf("%d", &price[i]);
        }
        for (int i = 0; i < m; i ++){
            int tmpu, tmpv, tmpw;
            scanf("%d %d %d", &tmpu, &tmpv, &tmpw);
            add(tmpu, tmpv, tmpw);
            add(tmpv, tmpu, tmpw);
        }
        int q, c, s, e;;
        scanf("%d", &q);
        while(q --){
            scanf("%d %d %d", &c, &s, &e);
            int ans = BFS(c, s, e);
            if (ans == -1){
                puts("impossible");
            }
            else{
                printf("%d\n", ans);
            }
        }
        return 0;
    }
    
     
    举杯独醉,饮罢飞雪,茫然又一年岁。 ------AbandonZHANG
  • 相关阅读:
    vue简单总结
    浅拷贝 与递归实现深拷贝封装
    利用mock生成随机的东西
    你不知道的JavaScript--面向对象高级程序设计
    超实用的JavaScript代码段 --倒计时效果
    超实用的JavaScript代码段 Item4 --发送短信验证码
    WEB前端性能优化:HTML,CSS,JS和服务器端优化
    超实用的JavaScript代码段 Item8 -- js对象的(深)拷贝
    web开发必须知道的javascripat工具
    加快页面的运行速度
  • 原文地址:https://www.cnblogs.com/AbandonZHANG/p/4114021.html
Copyright © 2011-2022 走看看