【最短路】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\n",minn);
73     return 0;
74 }

 

posted @ 2017-01-30 16:45  Etta19  阅读(302)  评论(0编辑  收藏  举报