码迷,mamicode.com
首页 > 其他好文 > 详细

最短路练习 poj1724

时间:2018-03-28 01:27:35      阅读:224      评论:0      收藏:0      [点我收藏+]

标签:lan   ret   operator   tput   return   ice   expressed   splay   memset   

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

Input

The first line of the input contains the integer K, 0 <= K <= 10000, maximum number of coins that Bob can spend on his way. 
The second line contains the integer N, 2 <= N <= 100, the total number of cities. 

The third line contains the integer R, 1 <= R <= 10000, the total number of roads. 

Each of the following R lines describes one road by specifying integers S, D, L and T separated by single blank characters : 
  • S is the source city, 1 <= S <= N 
  • D is the destination city, 1 <= D <= N 
  • L is the road length, 1 <= L <= 100 
  • T is the toll (expressed in the number of coins), 0 <= T <=100

Notice that different roads may have the same source and destination cities.

Output

The first and the only line of the output should contain the total length of the shortest path from the city 1 to the city N whose total toll is less than or equal K coins. 
If such path does not exist, only number -1 should be written to the output. 

Sample Input

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

Sample Output

11

K为可以支付的路费,N为目的地,R为道路数。
S、D、L、T分别为起始位置,终点位置,这条路的长度,这条路的路费。
路费相同时,输出长度最短的,长度相同时,输出路费最少的。

由此可以想到优先队列,最短路可以想到dijk。
Talk is cheap,show me the code.
技术分享图片
 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<queue>
 4 #define man 10005
 5 #define INF 1e7
 6 using namespace std;
 7 int num,k,n;///k为硬币数,n为目的地
 8 int fir[man];///邻接表的头
 9 struct node
10 {
11     int y,len,co;///y为下一城市,len为路程,co为路费
12 }node1;
13 
14 struct edge
15 {
16     int y,len,co,nex;///y为下一城市,len为路程,co为路费,nex用于存邻接表
17 }e[man];
18 
19 priority_queue <node> q;///将结构体装入优先队列
20 bool operator < (node a,node b)///优先队列的重载
21 {
22     return a.len>b.len;///路程短的放在前面
23 }
24 
25 void add(int u,int v,int len,int co)///存进e中
26 {
27     e[num].y=v;
28     e[num].len=len;
29     e[num].co=co;
30     e[num].nex=fir[u];
31     fir[u]=num;
32     num++;
33 }
34 int main()
35 {
36     node cur;
37     int ans=INF;///输出的答案
38     int r,s,d,l,t;///与题目中的字母含义相同
39     while( ~scanf("%d%d%d",&k,&n,&r)){
40         num=1;
41         while(!q.empty()) q.pop();
42         memset( fir, -1, sizeof fir);
43         for(int i=1;i<=r;i++){
44             scanf("%d%d%d%d",&s,&d,&l,&t);
45             add(s,d,l,t);
46         }
47         cur.y=1;
48         cur.len=0;
49         cur.co=0;
50         q.push(cur); ///第一个进队
51         while(!q.empty()){
52            cur=q.top();
53 //            printf("%d %d %d\n",cur.y,cur.len,cur.co);
54             q.pop();
55             if(cur.y==n){ ///因为优先队列由小到大排列,所以找到y与n相同时直接输出
56                 ans=cur.len;
57                 break;
58             }
59             for(int i=fir[cur.y];i!=-1;i=e[i].nex){///i用于访问邻接表
60                 if(k>=cur.co+e[i].co){///钱数不能大于可支付
61                     node1.co=e[i].co+cur.co;///进入优先队列
62                     node1.len=e[i].len+cur.len;
63                     node1.y=e[i].y;
64                     q.push(node1);
65                 }
66             }
67         }
68         if(ans==INF)
69             printf("-1\n");
70         else
71         printf("%d\n",ans);
72     }
73     return 0;
74 }
View Code

用邻接表和优先队列,dijk的效率大大提高了。

最短路练习 poj1724

标签:lan   ret   operator   tput   return   ice   expressed   splay   memset   

原文地址:https://www.cnblogs.com/ZQUACM-875180305/p/8661144.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!