最短路径问题
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 30126 Accepted Submission(s): 8905
Problem Description
给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
Input
输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点。n和m为0时输入结束。
(1<n<=1000, 0<m<100000, s != t)
(1<n<=1000, 0<m<100000, s != t)
Output
输出 一行有两个数, 最短距离及其花费。
Sample Input
3 2 1 2 5 6 2 3 4 5 1 3 0 0
Sample Output
9 11
用迪杰特斯拉算法,要注意的是有两个判断条件,当距离相同的时候要再对花费进行比较,
C++ Code
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
#include<bits/stdc++.h>
using namespace std; const int maxnint = 9999; struct node { int d; int v; }; node dis[ 1008]; ///存储原点到各点的最短距离 node Map[ 1008][ 100008]; ///存储图的邻接矩阵 int n, line; ///节点数,和路径数 void dijikstr( int n, int v, node dis[ 1008], node Map[ 1008][ 100008]) { bool s[ 1008]; for( int i = 1; i <= n; i++) { dis[i].d = Map[v][i].d; dis[i].v = Map[v][i].v; s[i] = 0; } s[v] = 1; s[v] = 0; for( int i = 2; i <= n; i++) { int temp1 = maxnint; int temp2 = maxnint; int u = v; for( int j = 1; j <= n; j++) { if((!s[j]) && dis[j].d != temp1) { if(dis[j].d < temp1) { u = j; temp1 = dis[j].d; temp2 = dis[j].v; } } else if((!s[j]) && dis[j].d == temp1) { if(dis[j].v < temp2) { u = j; temp1 = dis[j].d; temp2 = dis[j].v; } } } s[u] = 1; for( int j = 1; j <= n; j++) { if((!s[j]) && Map[u][j].d < maxnint) { int newdist1 = dis[u].d + Map[u][j].d; int newdist2 = dis[u].v + Map[u][j].v; if(dis[j].d > newdist1) { dis[j].d = newdist1; dis[j].v = newdist2; } else if(dis[j].d == newdist1) { if(dis[j].v > newdist2) { dis[j].d = newdist1; dis[j].v = newdist2; } } } } } } int main() { while(scanf( "%d %d", &n, &line)) { if(n == 0 || line == 0) break; int i, j; for( i = 1; i <= n; i++) { for(j = 1; j <= n; j++) { Map[i][j].d = Map[i][j].v = maxnint; } Map[i][i].d = Map[i][i].v = 0; } int a, b, d, v; for( int i = 1; i <= line; i++) { scanf( "%d %d %d %d", &a, &b, &d, &v); if(d < Map[a][b].d) { Map[a][b].d = d; Map[a][b].v = v; Map[b][a].v = v; Map[b][a].d = d; } else if(d == Map[a][b].d) { if(v < Map[a][b].v) { Map[a][b].d = d; Map[a][b].v = v; Map[b][a].v = v; Map[b][a].d = d; } } } for( int i = 1; i <= n; i++) dis[i].d = dis[i].v = maxnint; int xx, yy; scanf( "%d %d", &xx, &yy); dijikstr(n, xx, dis, Map); printf( "%d %d\n", dis[yy].d, dis[yy].v); } return 0; } |