zoukankan      html  css  js  c++  java
  • light oj 1254

    题目大意:n个点m条边的有向图,q次询问c,s,t,表示汽车邮箱容量为c,求从起点s到终点t的最小费用。汽车在每个点可以加任意的油,每个点的单位油价为a[i]。

    题目思路:利用最小费优先队列优化最短路,dist[u][use]代表到达u节点,剩余use单位汽油的花费值。

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<math.h>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #define MAXSIZE 1015
    #define INF 0x3f3f3f3f
    #define LL long long
    
    using namespace std;
    
    typedef pair<int,int>p;
    typedef pair<p,int>pp;
    
    int dist[MAXSIZE][105],val[105],a[2*MAXSIZE],k;
    
    struct node
    {
        int u;
        int v;
        int w;
        int next;
    } G[2*MAXSIZE];
    
    void Add(int u,int v,int w)
    {
        G[k].u=u;
        G[k].v=v;
        G[k].w=w;
        G[k].next=a[u];
        a[u]=k++;
    }
    
    int spfa(int s,int t,int c)
    {
        memset(dist,INF,sizeof(dist));
        priority_queue<pp,vector<pp>,greater<pp> >Q;
        dist[s][0]=0;
        Q.push(pp(p(dist[s][0],0),s)); // 按优先级顺序入队
        while(!Q.empty())
        {
            pp k=Q.top();
            Q.pop();
            int w=k.first.first; //已花费的钱
            int use=k.first.second; //剩余油量
            int u=k.second; //当前节点
            if(w > dist[u][use])
                continue;
            if(u==t) //最小费优先
                return dist[u][use];
            for(int i=a[u]; i!=-1; i=G[i].next)
            {
                int v=G[i].v;
                if(G[i].w > c)
                    continue;
                if(use >= G[i].w && dist[v][use - G[i].w] > dist[u][use]) //当前剩余油量足够到达v
                {
                    dist[v][use - G[i].w] = dist[u][use];
                    Q.push(pp(p(dist[v][use - G[i].w],use - G[i].w),v));
                }
    
            }
            if(use < c)//当前油量不足以到达下一个点,就向邮箱里加1个单位的汽油
            {
                dist[u][use+1] = dist[u][use] + val[u];
                Q.push(pp(p(dist[u][use+1],use+1),u));
            }
        }
        return INF;
    }
    
    void Init()
    {
        memset(a,-1,sizeof(a));
        k=1;
    }
    
    int main()
    {
        int T,n,m,c,s,t,u,v,w,cns=1;
        scanf("%d",&T);
        while(T--)
        {
            Init();
            scanf("%d%d",&n,&m);
            for(int i=0; i<n; i++)
                scanf("%d",&val[i]);
            for(int i=1; i<=m; i++)
            {
                scanf("%d%d%d",&u,&v,&w);
                Add(u,v,w);
                Add(v,u,w);
            }
            scanf("%d",&m);
            printf("Case %d:
    ",cns++);
            while(m--)
            {
                memset(dist,INF,sizeof(dist));
                scanf("%d%d%d",&c,&s,&t);
                int ans=spfa(s,t,c);
                if(ans != INF)
                    printf("%d
    ",ans);
                else
                    printf("impossible
    ");
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    python 字典
    python 列表、元组 for 循环
    python字符串
    python之while 循环 格式化、运算符、编码
    Python变量命名的规范、if else 条件语句
    Linux文件管理-主题2
    Linux系统管理-主题1
    Linux操作系统零基础入门学习3
    CCF--二十四点
    第一个Python程序
  • 原文地址:https://www.cnblogs.com/alan-W/p/6767349.html
Copyright © 2011-2022 走看看