题目描述:

给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
输入:                       
输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点t。n和m为0时输入结束。 (1<n<=1000, 0<m<100000, s != t)
输出:                       
输出 一行有两个数, 最短距离及其花费。
样例输入:                       
3 2
1 2 5 6
2 3 4 5
1 3
0 0
样例输出:                       
9 11通过这道题复习了一下迪杰特斯拉算法,算法的精髓在于每回找一个距离集合最近的点加到集合中,直到不能加入更多的点为止代码如下:
 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <string>
 5 #include <algorithm>
 6 #define MAX 999999999
 7 #define N 1005
 8 #define M 100005
 9
10 struct Way {
11     int distance;
12     int cost;
13 };
14
15 Way map[N][N];//邻接矩阵
16 Way dis[N];//起点到各个点的距离表
17 int flag[N];//判别某点是否在已包括点的集合中
18
19 void dijkstra(int start, int end,int n) {
20     memset(flag,0,sizeof(int)*N);
21     //初始化距离
22     for(int i = 1; i <= n; i++) {
23         dis[i] = map[start][i];
24     }
25     dis[start].distance = 0;//该点到自己的距离为0
26     dis[start].cost = 0;//到自己的花费为0
27     flag[start] = 1;//把自己包括到可以到达的点中
28
29     for(int i = 1; i < n; i++) {
30         //总共需要加入n-1个点,所以循环n-1次
31         int index = 0;
32         int min = MAX;
33         for(int j = 1; j <= n; j++) {
34             if(flag[j] == 0 && dis[j].distance < min) {
35                 index = j;
36                 min = dis[j].distance;
37             }
38         }
39         //find the min index
40         flag[index] = 1;
41
42         for(int j = 1; j <= n; j++) {
43             if(flag[j] == 0 && (dis[index].distance + map[index][j].distance < dis[j].distance)) {
44                 dis[j].distance = dis[index].distance + map[index][j].distance;
45                 dis[j].cost = dis[index].cost + map[index][j].cost;
46             }
47             else if(flag[j] == 0 && (dis[index].distance + map[index][j].distance == dis[j].distance)){
48                 if(dis[j].cost > dis[index].cost + map[index][j].cost) {
49                     dis[j].cost = dis[index].cost + map[index][j].cost;
50                 }
51             }
52         }
53     }
54
55
56 }
57
58 int main(int argc, char const *argv[])
59 {
60     int n,m;
61     int source, des;
62     scanf("%d %d",&n,&m);
63     while(n != 0 && m != 0) {
64         for(int i = 1; i <= n; i++) {
65             for(int j = 1; j <= n; j++) {
66                 map[i][j].distance = MAX;
67                 map[i][j].cost = MAX;
68             }
69         }
70         int pointA,pointB,disc,cost;
71         for(int i = 0; i < m; i++) {
72             scanf("%d %d %d %d",&pointA,&pointB,&disc,&cost);
73             map[pointA][pointB].distance = disc;
74             map[pointB][pointA].distance = disc;
75             map[pointA][pointB].cost = cost;
76             map[pointB][pointA].cost = cost;
77         }
78         scanf("%d %d",&source,&des);
79
80         dijkstra(source,des,n);
81         printf("%d %d\n",dis[des].distance,dis[des].cost);
82         scanf("%d %d",&n,&m);
83     }
84     return 0;
85 }

最近尝试了一下用优先队列来解决问题,感觉写得很别扭,不过还是写出来了,速度提高不少,代码如下

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <vector>
 4 #include <queue>
 5
 6 #define MAX_V 1002
 7 #define inf 999999999
 8 using namespace std;
 9
10 struct Edge
11 {
12 public:
13     int to;
14     int dis;
15     int cost;
16     Edge(int to, int dis,int cost) {
17         this->to = to;
18         this->dis = dis;
19         this->cost = cost;
20     }
21 };
22
23 struct cmp{
24     bool operator()(const Edge &a,const Edge &b){
25         if(a.dis == b.dis) {
26             return a.cost - b.cost;
27         }
28         else {
29             return a.dis - b.dis;
30         }
31     }
32 };
33 typedef pair<int , int> P;//first dis, sencond cost
34 P dist[MAX_V];
35 vector<Edge> G[MAX_V];
36 priority_queue<Edge, vector<Edge>, cmp> que;
37
38 int main(int argc, char const *argv[])
39 {
40     int n,m;
41     int source, des;
42     freopen("input.txt","r",stdin);
43     while(scanf("%d %d",&n,&m) != EOF && (n != 0 && m != 0)) {
44         for(int i = 0; i <= n; i++) {
45             G[i].clear();
46         }
47         for(int i = 0; i < m; i++) {
48             int a, b, disc, cost;
49             scanf("%d %d %d %d",&a,&b,&disc,&cost);
50             G[a].push_back(Edge(b,disc,cost));
51             G[b].push_back(Edge(a,disc,cost));
52         }
53         scanf("%d %d",&source,&des);
54         fill(dist,dist+n+1,P(inf,inf));
55         dist[source] = P(0,0);
56         que.push(Edge(source,0,0));
57
58         while(!que.empty()) {
59             Edge t = que.top(); que.pop();
60             int v = t.to, d = t.dis, c = t.cost;
61             if(dist[v].first < d) {
62                 continue;
63             }
64             for(int i = 0; i < G[v].size(); i++) {
65                 Edge &e = G[v][i];
66                 int d2 = d + e.dis;
67                 int c2 = c + e.cost;
68
69                 if(dist[e.to].first > d2 || (dist[e.to].first == d2 && dist[e.to].second > c2)) {
70                     dist[e.to] = P(d2,c2);
71                     que.push(Edge(e.to,d2,c2));
72                 }
73             }
74         }
75         printf("%d %d\n",dist[des].first,dist[des].second);
76
77     }
78     return 0;
79 }

转载于:https://www.cnblogs.com/jasonJie/p/5661595.html

九度oj题目1008:最短路径问题相关推荐

  1. 九度OJ 题目1179:阶乘

    /********************************* * 日期:2013-2-8 * 作者:SJF0115 * 题号: 九度OJ 题目1179:阶乘 * 来源:http://ac.jo ...

  2. 九度OJ 题目1069:查找学生信息 随笔

    ** 九度OJ 题目1069:查找学生信息 ** 题目描述如下: 输入N个学生的信息,然后进行查询. 输入 输入的第一行为N,即学生的个数(N<=1000) 接下来的N行包括N个学生的信息,信息 ...

  3. 九度OJ 题目1203:IP地址

    /********************************* * 日期:2013-2-8 * 作者:SJF0115 * 题号: 九度OJ 题目1203:IP地址 * 来源:http://ac. ...

  4. 【九度OJ】1008【加权无向图最短路径】

    在网上查了一下,加权无向图最短路解法DFS和Dijkstra多一些,一般不用BFS 我选择用DFS,用时380MS,看了一下其他人的,最好的是240MS,用的是Dijkstra.都是采用邻接矩阵存储图 ...

  5. 九度OJ—题目1032:ZOJ

    题目描写叙述: 读入一个字符串.字符串中包括ZOJ三个字符,个数不一定相等,按ZOJ的顺序输出.当某个字符用完时,剩下的仍然依照ZOJ的顺序输出. 输入: 题目包括多组用例,每组用例占一行,包括ZOJ ...

  6. 九度oj 题目1411:转圈

    题目描述: 在一个有向图有n个顶点(编号从1到n),给一个起点s,问从起点出发,至少经过一条边,回到起点的最短距离. 输入: 输入包括多组,每组输入第一行包括三个整数n,m,s(1<=n< ...

  7. 【WA】九度OJ题目1435:迷瘴

    题目描述: 通过悬崖的yifenfei,又面临着幽谷的考验-- 幽谷周围瘴气弥漫,静的可怕,隐约可见地上堆满了骷髅.由于此处长年不见天日,导致空气中布满了毒素,一旦吸入体内,便会全身溃烂而死. 幸好y ...

  8. 九度oj 题目1354:和为S的连续正数序列

    题目描述: 小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100.但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数).没多久, ...

  9. 九度oj 题目1376:最近零子序列

    题目描述: 给定一个整数序列,你会求最大子串和吗?几乎所有的数据结构与算法都会描述求最大子串和的算法.今天让大家来算算最近0子串和,即整数序列中最接近0的连续子串和.例如,整数序列6, -4, 5, ...

最新文章

  1. MySQL INSERT:插入数据(添加数据)
  2. C#、.Net经典面试题目及答案
  3. 8.Excel数据与指标概述
  4. 计算机机房t4,机房等级-T2-T3-T4-如何划分
  5. Windows句柄和指针的区别
  6. 实验五 数据结构综合应用 20162305
  7. 2008年十大IT图书评选第一周幸运读者获奖名单(每周更新)
  8. Java ResourceBundle 加载外部路径资源文件方式
  9. 生活大爆炸第二季 那些精妙的台词翻译
  10. 用Python实现从Oracle到GreenPlum的表结构转换
  11. 电脑ppt录制微课软件哪个好 电脑ppt录制微课的方法
  12. mingw+msys windows下配置
  13. 什么是分布式,分布式和集群的区别又是什么?
  14. 是时候更新Android Studio 3.5了!不信,你看~
  15. 基于Ha-Joker靶场的完整渗透测试演示直至提权(root)
  16. 打工人的快乐星球,还存在吗?
  17. Python基础 day3
  18. 微型计算机原理第三版考试,微机原理试题及答案
  19. 「JAVA知识每日一问」:Redis6.0为什么引入多线程?
  20. 记一次前端大厂面试 | 掘金技术征文

热门文章

  1. vue 指令 v-cloak
  2. Spring @ComponentScan
  3. python threading.lock
  4. TensorFlow tf.keras.losses.MeanSquaredError
  5. property java用法_Java Properties getProperty(key)用法及代码示例
  6. sip 时序图_Tcl与Design Compiler (五)——综合库(时序库)和DC的设计对象(下)
  7. Exchange Reporter Plus概述
  8. JavaScript学习总结(3)——JavaScript函数(function)
  9. var和function谁先优先执行_浅谈JavaScript 的执行顺序
  10. 详解 equals() 方法和 hashCode() 方法