1008.最短路径问题
2014-04-25 19:55
169 查看
题目描述:
给你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
典型的迪杰斯特拉(Dijkstra)算法。关于图的表示方法有两种,一种是采用邻接矩阵,一种采用邻接表。
采用邻接矩阵的最重要的就是三个数组:
1.c[][]:图的表示方法。
2.dist[]:表示当前点到源点的最短距离。
3.known[]:表示该点是否被访问过。
下面是一个标准的求最短路径的Dijkstra算法代码:
测试用例:
5 7
1 2 10
1 4 30
1 5 100
2 3 50
3 5 10
4 3 20
4 5 60
1 5
3 2
1 2 5
2 3 4
1 3
输出:60 9
此题涉及到距离和花费,不像传统的最短路径算法只要求最短路径,所以可以设立一个结构体。用来记录每个节点的距离和花费。这题WA了很久,原因是数据很变态。把最大值开大一点就OK~
给你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
典型的迪杰斯特拉(Dijkstra)算法。关于图的表示方法有两种,一种是采用邻接矩阵,一种采用邻接表。
采用邻接矩阵的最重要的就是三个数组:
1.c[][]:图的表示方法。
2.dist[]:表示当前点到源点的最短距离。
3.known[]:表示该点是否被访问过。
下面是一个标准的求最短路径的Dijkstra算法代码:
测试用例:
5 7
1 2 10
1 4 30
1 5 100
2 3 50
3 5 10
4 3 20
4 5 60
1 5
3 2
1 2 5
2 3 4
1 3
输出:60 9
#include <iostream> using namespace std; const int MaxInt = 999999; const int MaxNum = 100000; int c[MaxNum][MaxNum]; //邻接矩阵 int dist[MaxNum]; //每个节点到源点的最短距离 bool visited[MaxNum]; //每个节点是否访问过 void Dijkstra(int s, int n) { for(int i = 1; i <= n; ++i) dist[i] = c[s][i]; dist[s] = 0; visited[s] = true; //依次访问接下来的n - 1个unknown节点 for(int i = 1; i <= n - 1; ++i) { int tmp = MaxInt; //当前最短距离 int v = s; // 当前的节点 //在所有unknown节点中找到和源点距离最短的节点 for(int j = 1; j <= n; ++j) { if(!visited[j] && dist[j] < tmp) { v = j; tmp = dist[j]; } } //找到了和源点距离最短的unknown节点,更改其访问数组 visited[v] = true; //然后更新其邻接的边,所有的边都要访问一次,都可能会更新 for(int j = 1; j <= n; ++j) { if(!visited[j] && c[v][j] < MaxInt) { int tmp_dist = dist[v] + c[v][j]; if(tmp_dist < dist[j]) dist[j] = tmp_dist; } } } } int main() { int n,line; // n代表节点数目,line代表路径数 while(cin >> n >> line) { //跳出条件 if(n == 0 && line == 0) break; //初始化邻接矩阵 for(int i = 1; i <= n; ++i) for(int j = 1; j <= n; ++j) c[i][j] = MaxInt; for(int i = 0; i < line; ++i) { int p,q,len; cin >> p >> q >> len; if(len < c[p][q])//如果有重边 { c[p][q] = len; c[q][p] = len; //无向图 如果有向图这句话就去掉 } } //初始化最短距离 for(int i = 1; i <= n; ++i) dist[i] = MaxInt; //初始化访问数组 for(int i = 1; i <= n; ++i) visited[i] = false; int s,t; //s,t分别为需要求的两点 cin >> s >> t; Dijkstra(s,n); cout << dist[t] << endl; } return 0; }
此题涉及到距离和花费,不像传统的最短路径算法只要求最短路径,所以可以设立一个结构体。用来记录每个节点的距离和花费。这题WA了很久,原因是数据很变态。把最大值开大一点就OK~
#include <iostream> using namespace std; const int MaxInt = 1000000000 ; const int MaxNum = 1001; struct Node { int len; int cost; }; Node c[MaxNum][MaxNum]; //图的表示数组 Node dist[MaxNum]; //每个节点到源点的最短距离以及花费 bool visited[MaxNum]; //每个节点是否访问过 void Dijkstra(int s, int n) { for(int i = 1; i <= n; ++i) { dist[i].len = c[s][i].len; dist[i].cost = c[s][i].cost; } dist[s].len = 0; dist[s].cost = 0; visited[s] = true; //依次访问接下来的n - 1个unknown节点 for(int i = 1; i <= n - 1; ++i) { int tmp = MaxInt; //当前最短距离 int v = s; // 当前的节点 //在所有unknown节点中找到和源点距离最短的节点 for(int j = 1; j <= n; ++j) { if(!visited[j] && dist[j].len < tmp) { v = j; tmp = dist[j].len; } } //找到了和源点距离最短的unknown节点,更改其访问数组 visited[v] = true; //然后更新其邻接的边,所有的边都要访问一次,都可能会更新 for(int j = 1; j <= n; ++j) { if(!visited[j] && c[v][j].len < MaxInt) { int tmp_len = dist[v].len + c[v][j].len; int tmp_cost = dist[v].cost + c[v][j].cost; if(tmp_len < dist[j].len) { dist[j].len = tmp_len; dist[j].cost = tmp_cost; } else if(tmp_len == dist[j].len && tmp_cost < dist[j].cost) { dist[j].cost = tmp_cost; } } } } } int main() { int n,line; // n代表节点数目,line代表路径数 while(cin >> n >> line) { //跳出条件 if(n == 0 && line == 0) break; //初始化邻接矩阵 for(int i = 1; i <= n; ++i) for(int j = 1; j <= n; ++j) { c[i][j].len = MaxInt; c[i][j].cost = MaxInt; } for(int i = 0; i < line; ++i) { int p,q,len,cost; cin >> p >> q >> len >> cost; if(len < c[p][q].len || (len == c[p][q].len && cost < c[p][q].cost))//如果有重边 { c[p][q].len = len; c[q][p].len = len; c[p][q].cost = cost; c[q][p].cost = cost; } } //初始化最短距离 for(int i = 1; i <= n; ++i) { dist[i].len = MaxInt; dist[i].cost = MaxInt; } //初始化访问数组 for(int i = 1; i <= n; ++i) visited[i] = false; int s,t; //s,t分别为需要求的两点 cin >> s >> t; Dijkstra(s,n); cout << dist[t].len << " " << dist[t].cost << endl; } return 0; }
相关文章推荐
- 题目1008:最短路径问题
- 九度OJ-题目1008 最短路径问题
- [九度OJ]1008.最短路径问题
- 九度oj 题目1008:最短路径问题
- 题目1008:最短路径问题
- 九度题目1008:最短路径问题
- 九度1008:最短路径问题(Dijkstra)
- 题目1008:最短路径问题
- 九度 OJ 题目1008:最短路径问题 (Dijstra 算法)
- 九度 题目1008:最短路径问题
- 九度 OJ 1008 最短路径问题
- 题目1008:最短路径问题
- 题目1008:最短路径问题
- 九度oj-1008-最短路径问题
- 九度OJ 题目1008:最短路径问题
- 九度OJ——1008最短路径问题
- 题目1008:最短路径问题
- Jobdu 题目1008:最短路径问题
- 题目1008:最短路径问题
- 题目1008:最短路径问题