• 【最短路】hxk化学课


    版权声明:本篇随笔版权归作者Etta(http://www.cnblogs.com/Etta/)所有,转载请保留原地址!

    问题描述

    Nc回到教室上化学课,化学老师为了考考他, 拿来了好多试验用的药品. 他告诉了nc一开始的物质, m个化学方程式, 和他最终需要的产物, 让nc制作出来. 化学老师把一开始的物质编号为1, 最终产物编号为n. 所有可能出现的中间产物从2到n-1编号. 每次把一个物质变成另一个物质, 需要加入一些溶液, 反应需要一定的时间, 并且会产生一些花费. 化学老师说, 他只给nc k元, 让nc在资金范围内尽快完成实验.并告诉他这个最短时间.

    输入文件

    第一行包含一个整数k, 为nc的资金.

    第二行包含一个整数n, 为物质总数.第三行包含一个整数m, 为老师给的化学方程式的个数.接下来m行, 每行包含4个整数a,b,t,c.表示物质a可以变成物质b, 需要t的时间, c的花费.输出文件

    如果nc无法完成实验, 输出-1. 否则输出资金允许的最短时间.

    样例输入

    5

    6

    7

    1 2 2 3

    2 4 3 3

    3 4 2 4

    1 3 4 1

    4 6 2 1

    3 5 2 0

    5 4 3 2

    样例输出

    11

    输入输出样例解释

    Nc先花4的时间1的花费将1物质变成3物质, 然后花2的时间0的花费将3物质变成5物质. 接着花3的时间2的花费将5物质变成4物质, 最后花2的时间1的花费将4物质变成6物质.

    总时间=4+2+3+2=11; 总花费=1+0+2+1=4<5.

    数据范围和约定

    对于20% 的数据, n<=12.对于100% 的数据, 0<=k<=10000, 2<=n<=100,1<=m<=10000,0<=t<=100,0<=c<=100.

     

    一、分析问题

           这是一个二维最短路问题。

    二、解决问题

           Pair队列的二维处理+SPFA

    Tips:同类型题:LightOJ 1281

    三、代码实现

     1 #include<cstdio>
     2 #include<queue>
     3 using namespace std;
     4 
     5 const int A=10010,B=110,inf=4e8;
     6 
     7 typedef pair<int,int>pii;
     8 int n,m,k,a,b,tt,cc,sum;
     9 int dis[B][A],ex[B][A],head[B];
    10 struct edge{
    11     int to,nxt,t,c;
    12 }e[A*2];
    13 queue<pii>q;
    14 
    15 void build(int a,int b,int t,int c)
    16 {
    17     e[++sum].to=b;
    18     e[sum].t=t;
    19     e[sum].c=c;
    20     e[sum].nxt=head[a];
    21     head[a]=sum;
    22 }
    23 
    24 void SPFA()
    25 {
    26     for(int i=1;i<=n;++i)
    27         for(int j=0;j<=k;++j)
    28             dis[i][j]=inf;
    29     
    30     dis[1][0]=0;ex[1][0]=1;
    31     pii r;
    32     r.first=1;
    33     r.second=0;
    34     q.push(r);
    35     while(!q.empty())
    36     {
    37         pii j=q.front();
    38         q.pop();
    39         int u=j.first,s=j.second;
    40         ex[u][s]=0;
    41         for(int i=head[u];i;i=e[i].nxt)
    42         {
    43             int w=e[i].t,c=e[i].c+s,to=e[i].to;
    44             if(dis[to][c]>dis[u][s]+w&&c<=k)
    45             {
    46                 dis[to][c]=dis[u][s]+w;
    47                 if(!ex[to][c])
    48                 {
    49                     ex[to][c]=1;
    50                     r.first=to;
    51                     r.second=c;
    52                     q.push(r);
    53                 }
    54             }
    55         }
    56     }
    57 }
    58 
    59 int main()
    60 {
    61     scanf("%d%d%d",&k,&n,&m);
    62     for(int i=1;i<=m;++i)
    63     {
    64         scanf("%d%d%d%d",&a,&b,&tt,&cc);
    65         build(a,b,tt,cc);
    66     }
    67     SPFA();
    68     int minn=inf;
    69     for(int i=0;i<=k;++i)
    70         if(dis[n][i]<minn)minn=dis[n][i];
    71     if(minn==inf)printf("-1");
    72     else printf("%d
    ",minn);
    73     return 0;
    74 }
  • 相关阅读:
    「LOJ #6500」「雅礼集训 2018 Day2」操作
    「CEOI2013」Board
    CF407B Long Path
    poj 2503 Babelfish 用trie树做
    poj 3414 Pots搜索BFS
    POJ2001 Shortest Prefixes 用trie树实现
    poj3630Phone List用trie树实现
    poj1797Heavy Transportation最大生成树
    hoj题双重筛法
    poj1338 Ugly Numbers
  • 原文地址:https://www.cnblogs.com/Etta/p/6358163.html
Copyright © 2020-2023  润新知