POJ 1724 ROADS(使用邻接表和优先队列的BFS求解最短路问题)

题目链接:

https://cn.vjudge.net/problem/POJ-1724

N cities named with numbers 1 ... N are connected with one-way roads. Each road has two parameters associated with it : the road length and the toll that needs to be paid for the road (expressed in the number of coins).
Bob and Alice used to live in the city 1. After noticing that
Alice was cheating in the card game they liked to play, Bob broke up
with her and decided to move away - to the city N. He wants to get there
as quickly as possible, but he is short on cash.

We want to help Bob to find
the shortest path from the city 1 to the city N
that he can afford with the amount of money he has.

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
 1 /*
 2 题意描述
 3 输入总钱数k,顶点数n,边数m
 4 每一条边s到d长度是l,花费是t
 5 可能有重边
 6 问在不超过k的前提下,从1到n的最短路径是多少,如果不存在这样的最短路输出-1.
 7
 8 解题思路
 9 使用用优先队列的广搜,保证每次弹出的结点是距离最短,而且花费相对小的,搜索的时候不用像矩阵中那样标记哪个结点用过了,因为使用
10 的是每个结点的邻接边,标记了可能就不能用这条边了,故直接搜索。还需注意的是一定要是弹出的结点是终点再结束,如果在搜索的时候遇
11 到直接结束,可能这条路径不是最短的,但是从优先队列里第一个弹出的一定是最短的。
12 */
13 #include<cstdio>
14 #include<vector>
15 #include<queue>
16 #include<cstring>
17 const int maxn = 110;
18 const int INF = 0x3f3f3f3f;
19 using namespace std;
20
21 struct Edge{
22     int from, to, dist, pay;
23     Edge(int s, int d, int l, int t) : from(s), to(d), dist(l), pay(t) { };
24 };
25
26 struct HeapNode {
27     int u, d, c;
28     bool operator < (const HeapNode& a) const {
29         if(d == a.d){
30             return c > a.c;
31         }
32         return d > a.d;
33     }
34 };
35
36 struct BFS {
37     int n,m;
38     vector<Edge> edges;
39     vector<int> G[maxn];
40     bool done[maxn];
41
42     void init(int n) {
43         this->n = n;
44         for(int i = 0; i < n; i++)
45             G[i].clear();
46         edges.clear();
47     }
48
49     void AddEdge(int from, int to, int dist, int pay) {
50         edges.push_back(Edge(from, to, dist, pay));
51         m = edges.size();
52         G[from].push_back(m - 1);
53     }
54
55     int bfs(int k, int s) {
56         memset(done, 0, sizeof(done));
57         done[s] = 1;
58
59         priority_queue<HeapNode> q;
60         q.push((HeapNode){s, 0, 0});
61         while(!q.empty()) {
62             HeapNode x = q.top();
63             q.pop();
64             int u = x.u;
65             if(u == n - 1)
66                 return x.d;
67             for(int i = 0; i < G[u].size(); i++) {
68                 Edge e = edges[G[u][i]];
69                 if(k >= e.pay + x.c)
70                     q.push((HeapNode){e.to, x.d+e.dist, e.pay + x.c});
71             }
72         }
73         return -1;
74     }
75 };
76
77 struct BFS solve;
78 int main()
79 {
80     int k, n, m, s, d, l, t;
81     while(scanf("%d", &k) != EOF) {
82         scanf("%d%d", &n, &m);
83
84         solve.init(n);
85         for(int i = 1; i <= m; i++) {
86             scanf("%d%d%d%d",&s, &d, &l, &t);
87             s--;d--;
88             solve.AddEdge(s, d, l, t);//先--再使用
89         }
90
91         printf("%d\n", solve.bfs(k,0));
92     }
93     return 0;
94 } 

原文地址:https://www.cnblogs.com/wenzhixin/p/9383087.html

时间: 2024-10-13 09:50:31

POJ 1724 ROADS(使用邻接表和优先队列的BFS求解最短路问题)的相关文章

poj 1724 ROADS (bfs+优先队列)

题目链接 题意:在有费用k限制的条件下,求从1到n的最短距离,如果最短距离相同求费用最小的,边为有向边,其中可能有 多个相同的源点和目标点,但是距离和费用不同. 分析:用bfs和邻接表来把每一个边搜一下,因为用了优先队列,所以先到n的一定是最小的 . 1 #include <iostream> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <cstdio&

poj 1724 ROADS 解题报告

题目链接:http://poj.org/problem?id=1724 题目意思:给出一个含有N个点(编号从1~N).R条边的有向图.Bob 有 K 那么多的金钱,需要找一条从顶点1到顶点N的路径(每条边需要一定的花费),前提是这个总花费  <= K. 首先这里很感谢 yunyouxi0 ,也就是我们的ACM队长啦~~~,他一下子指出了我的错误——存储重边的错误.这条题卑鄙的地方是,有重边,discuss 中的数据过了也不一定会AC啦.大家不妨试试这组数据(队长深情奉献^_^) 2 2 2 1

poj 1724 ROADS(dfs)

http://poj.org/problem?id=1724 大致题意:N个城市由R条单向路连通,每条路(S,D)之间有两个因素:路的长度L和路的花费T.现要从城市1到达城市N,求花费在K以内的最短路程. 思路:很明显的dfs(他们都说很明显的spfa...).不过dfs有几点注意的地方: 建立邻接表不能用vector存,要用链表的形式,采用头插法. dfs的时候,在递归节点v之前,要先预判断一下到达v之后总花费是否大于k,若大于K就跳过,不必再调用v节点,这样会省很多时间.对于路程的处理也同样

poj 1724:ROADS(DFS + 剪枝)

ROADS Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10777   Accepted: 3961 Description N cities named with numbers 1 ... N are connected with one-way roads. Each road has two parameters associated with it : the road length and the toll

POJ 1724 ROADS

点击打开链接 ROADS Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10202   Accepted: 3786 Description N cities named with numbers 1 ... N are connected with one-way roads. Each road has two parameters associated with it : the road length and t

深搜+剪枝 POJ 1724 ROADS

POJ 1724 ROADS Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 12766   Accepted: 4722 Description N cities named with numbers 1 ... N are connected with one-way roads. Each road has two parameters associated with it : the road length and

ACM:最短路,dijkstra,邻接表的建立,使用邻接表跟优先队列的dijkstra,Bellman-Ford,Floyd。。

(一)dijkstra,邻接矩阵 所有边权均为正,不管有没有环,求单个源点出发,到所有节点的最短路.该方法同时适用于有向图和无向图. #include <iostream> #include <string> #include <stack> using namespace std; const int MAXN = 1000; const int INF = 100000000; int n, m; int maze[MAXN][MAXN], vis[MAXN], d

POJ 1511 Invitation Cards 邻接表 spfa算法

原题: http://poj.org/problem?id=1511 题目大意: 单向图,需要从点1到每个点去一次,去了马上回来,再去下一个点,求往返路径和. 如果只有100个点,跑一遍floyd就可以了,这里有10w个点,不行. 朴素的dijkstra是N^2的复杂度,这里要超时. 所以这里我们用spfa这种接近2N的算法. 由于二维数组空间不够,所以只能用vector或者邻接表,因为vector的适合经常修改,本身是链表结构,每次插入数据都会消耗时间来申请内存并和前面建立联系,虽然可以支持下

用邻接表实现DFS和BFS

#include <stdio.h> #include <stdlib.h> #define MAXVERTEX 10 typedef char VertexType; //顶点类型 typedef int EdgeType; //边的类型 typedef int ElemType; //队列中元素类型 typedef struct EdgeNode { int adjvex; EdgeType weight; struct EdgeNode *next; }EdgeNode; /