题目描述:

给你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
通过这道题复习了一下迪杰特斯拉算法,算法的精髓在于每回找一个距离集合最近的点加到集合中,直到不能加入更多的点为止
代码如下:
 #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#define MAX 999999999
#define N 1005
#define M 100005 struct Way {
int distance;
int cost;
}; Way map[N][N];//邻接矩阵
Way dis[N];//起点到各个点的距离表
int flag[N];//判别某点是否在已包括点的集合中 void dijkstra(int start, int end,int n) {
memset(flag,,sizeof(int)*N);
//初始化距离
for(int i = ; i <= n; i++) {
dis[i] = map[start][i];
}
dis[start].distance = ;//该点到自己的距离为0
dis[start].cost = ;//到自己的花费为0
flag[start] = ;//把自己包括到可以到达的点中 for(int i = ; i < n; i++) {
//总共需要加入n-1个点,所以循环n-1次
int index = ;
int min = MAX;
for(int j = ; j <= n; j++) {
if(flag[j] == && dis[j].distance < min) {
index = j;
min = dis[j].distance;
}
}
//find the min index
flag[index] = ; for(int j = ; j <= n; j++) {
if(flag[j] == && (dis[index].distance + map[index][j].distance < dis[j].distance)) {
dis[j].distance = dis[index].distance + map[index][j].distance;
dis[j].cost = dis[index].cost + map[index][j].cost;
}
else if(flag[j] == && (dis[index].distance + map[index][j].distance == dis[j].distance)){
if(dis[j].cost > dis[index].cost + map[index][j].cost) {
dis[j].cost = dis[index].cost + map[index][j].cost;
}
}
}
} } int main(int argc, char const *argv[])
{
int n,m;
int source, des;
scanf("%d %d",&n,&m);
while(n != && m != ) {
for(int i = ; i <= n; i++) {
for(int j = ; j <= n; j++) {
map[i][j].distance = MAX;
map[i][j].cost = MAX;
}
}
int pointA,pointB,disc,cost;
for(int i = ; i < m; i++) {
scanf("%d %d %d %d",&pointA,&pointB,&disc,&cost);
map[pointA][pointB].distance = disc;
map[pointB][pointA].distance = disc;
map[pointA][pointB].cost = cost;
map[pointB][pointA].cost = cost;
}
scanf("%d %d",&source,&des); dijkstra(source,des,n);
printf("%d %d\n",dis[des].distance,dis[des].cost);
scanf("%d %d",&n,&m);
}
return ;
}

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

 #include <cstdio>
#include <algorithm>
#include <vector>
#include <queue> #define MAX_V 1002
#define inf 999999999
using namespace std; struct Edge
{
public:
int to;
int dis;
int cost;
Edge(int to, int dis,int cost) {
this->to = to;
this->dis = dis;
this->cost = cost;
}
}; struct cmp{
bool operator()(const Edge &a,const Edge &b){
if(a.dis == b.dis) {
return a.cost - b.cost;
}
else {
return a.dis - b.dis;
}
}
};
typedef pair<int , int> P;//first dis, sencond cost
P dist[MAX_V];
vector<Edge> G[MAX_V];
priority_queue<Edge, vector<Edge>, cmp> que; int main(int argc, char const *argv[])
{
int n,m;
int source, des;
freopen("input.txt","r",stdin);
while(scanf("%d %d",&n,&m) != EOF && (n != && m != )) {
for(int i = ; i <= n; i++) {
G[i].clear();
}
for(int i = ; i < m; i++) {
int a, b, disc, cost;
scanf("%d %d %d %d",&a,&b,&disc,&cost);
G[a].push_back(Edge(b,disc,cost));
G[b].push_back(Edge(a,disc,cost));
}
scanf("%d %d",&source,&des);
fill(dist,dist+n+,P(inf,inf));
dist[source] = P(,);
que.push(Edge(source,,)); while(!que.empty()) {
Edge t = que.top(); que.pop();
int v = t.to, d = t.dis, c = t.cost;
if(dist[v].first < d) {
continue;
}
for(int i = ; i < G[v].size(); i++) {
Edge &e = G[v][i];
int d2 = d + e.dis;
int c2 = c + e.cost; if(dist[e.to].first > d2 || (dist[e.to].first == d2 && dist[e.to].second > c2)) {
dist[e.to] = P(d2,c2);
que.push(Edge(e.to,d2,c2));
}
}
}
printf("%d %d\n",dist[des].first,dist[des].second); }
return ;
}

九度oj题目1008:最短路径问题的更多相关文章

  1. 九度OJ 题目1384:二维数组中的查找

    /********************************* * 日期:2013-10-11 * 作者:SJF0115 * 题号: 九度OJ 题目1384:二维数组中的查找 * 来源:http ...

  2. hdu 1284 关于钱币兑换的一系列问题 九度oj 题目1408:吃豆机器人

    钱币兑换问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  3. 九度oj题目&amp;吉大考研11年机试题全解

    九度oj题目(吉大考研11年机试题全解) 吉大考研机试2011年题目: 题目一(jobdu1105:字符串的反码).    http://ac.jobdu.com/problem.php?pid=11 ...

  4. 九度oj 题目1007:奥运排序问题

    九度oj 题目1007:奥运排序问题   恢复 题目描述: 按要求,给国家进行排名. 输入:                        有多组数据. 第一行给出国家数N,要求排名的国家数M,国家号 ...

  5. 九度oj 题目1087:约数的个数

    题目链接:http://ac.jobdu.com/problem.php?pid=1087 题目描述: 输入n个整数,依次输出每个数的约数的个数 输入: 输入的第一行为N,即数组的个数(N<=1 ...

  6. 九度OJ题目1105:字符串的反码

    tips:scanf,cin输入字符串遇到空格就停止,所以想输入一行字符并保留最后的"\0"还是用gets()函数比较好,九度OJ真操蛋,true?没有这个关键字,还是用1吧,还是 ...

  7. 九度oj题目1009:二叉搜索树

    题目描述: 判断两序列是否为同一二叉搜索树序列 输入:                        开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束. 接 ...

  8. 九度oj题目1002:Grading

    //不是说C语言就是C++的子集么,为毛printf在九度OJ上不能通过编译,abs还不支持参数为整型的abs()重载 //C++比较正确的做法是#include<cmath.h>,cou ...

  9. 九度OJ题目1003:A+B

    while(cin>>str1>>str2)就行了,多简单,不得不吐槽,九度的OJ真奇葩 题目描述: 给定两个整数A和B,其表示形式是:从个位开始,每三位数用逗号", ...

随机推荐

  1. kafka java api生产者

    import java.util.HashMap; import java.util.List;import java.util.Map;import java.util.Properties; im ...

  2. tar打包压缩命令

    1. tar命令 用法: tar [选项...] [FILE]... GNU ‘tar’将许多文件一起保存至一个单独的磁带或磁盘归档,并能从归档中单独还原所需文件. 示例 tar -cf archiv ...

  3. Java编程基础-选择和循环语句

    一.选择结构语句 选择结构:也被称为分支结构.选择结构有特定的语法规则,代码要执行具体的逻辑运算进行判断,逻辑运算的结果有两个,所以产生选择,按照不同的选择执行不同的代码. Java语言提供了两种选择 ...

  4. DataGridView使用技巧(七、设定列宽和行高自动调整)----.NET

    DataGridView使用技巧(七.设定列宽和行高自动调整)----.NET 1) 设定行高和列宽自动调整 [VB.NET]' 设定包括Header和所有单元格的列宽自动调整DataGridView ...

  5. RAM建模和初始化

    冯诺依曼提出的存储计算,计算存储,因此,几乎所有的CPU和ASIC都会使用存储器,它们的类型很多,包括异步RAM.同步RAM.ZBT RAM.DDR DRAM.ROM等.由于大部分的异步RAM和SRA ...

  6. 在使用线程池时应特别注意对ThreadLocal的使用

    使用ThreadLocal并且有线程池时要特别注意,ThreadLocal是以线程为key的,而线程池里面的线程是会被重新利用的,所以如果有使用线程池并且使用ThreadLocal来保存状态信息时要特 ...

  7. java 核心技术卷一笔记 6 .2.3 接口 lambda 表达式 内部类

    6.2.3   对象克隆 Cloneable 接口,这个接口指示一个类提供了一个安全的clone方法.(稍作了解) 为一个对象引用的变量建立副本时,原变量和副本都是同一个对象的引用,任何一个变量改变都 ...

  8. C++通讯录

    C++通讯录1.0 历时一天,终于把通讯录写好了. 项目要求: 编写一个通讯录管理程序. 有一已存在的通讯录文件,数据内容为各联系人信息. 每个联系人信息的组成部分为: 姓名.电话号码和住址 等个人基 ...

  9. 换个语言学一下 Golang (5)——运算符

    运算符用于在程序运行时执行数学或逻辑运算. Go 语言内置的运算符有: 算术运算符 关系运算符 逻辑运算符 位运算符 赋值运算符 其他运算符 接下来让我们来详细看看各个运算符的介绍. 算术运算符 下表 ...

  10. Eclipse调试:项目在Debug模式下,无法启动的问题

    问题:Eclipse中调试Java项目时,使用正常模式:Run 项目名,可以正常启动.当想打断点调试时,点击Debug按钮后,项目显示 Source not found,或者弹出窗口显示服务器在45秒 ...