Problem Description
做为一个资深驴友,小新有一张珍藏的自驾游线路图,图上详细的标注了全国各个城市之间的高速公路距离和公路收费情况,现在请你编写一个程序,找出一条出发地到目的地之间的最短路径,如果有多条路径最短,则输出过路费最少的一条路径。
Input
连续T组数据输入,每组输入数据的第一行给出四个正整数N,M,s,d,其中N(2 <= N <= 500)是城市数目,城市编号从0~N-1,M是城市间高速公路的条数,s是出发地的城市编号,d是目的地的城市编号;随后M行,每行给出一条高速公路的信息,表示城市1、城市2、高速公路长度、收费额,中间以空格间隔,数字均为整数且不超过500,输入数据均保证有解。
Output
在同一行中输出路径长度和收费总额,数据间用空格间隔。
Example Input
1 4 5 0 3 0 1 1 20 1 3 2 30 0 3 4 10 0 2 2 20 2 3 1 20
Example Output
3 40
//最短路问题#include <bits/stdc++.h> #define N 600 #define INF 999999//无穷大 using namespace std; int dis[N];//保存每个点到起点最短距离 int cost[N];//保存到每个点时的花费 struct node { int l;//距离 int p;//花费 } Map[N][N]; int dijkstra(); int vis[N]; void start();//进行一些初始化操作 int n, m, s,d; int main() { int t; scanf("%d", &t); while(t--) { int u, v; int a, b; scanf("%d %d %d %d", &n, &m, &s, &d); start(); for(int i = 0; i < m; i++) { scanf("%d%d", &u, &v); scanf("%d%d", &a, &b); Map[u][v].p = Map[v][u].p = b; Map[u][v].l = Map[v][u].l = a; } dijkstra(); } return 0; } void start() { int i, j; for(i = 0; i < n; i++) { vis[i] = 0; for(j = 0; j < n; j++) { Map[i][j].l = Map[i][j].p = INF;//所有点初始化为距离无穷远, 也就是不连通 } } } int dijkstra() { for(int i = 0; i < n; i++)//初始化每个点到起始点的距离和花费 { dis[i] = Map[s][i].l; cost[i] = Map[s][i].p; } vis[s] = 1;//标记起始点已被访问 dis[s] = 0; for(int t = 1; t < n; t ++)//一共要找出n - 1个节点 { int Min = INF; int index; for(int i = 0; i < n; i++) { if(!vis[i] && Min > dis[i]) { Min = dis[i]; index = i;//找出距离起始点最近的点 } } vis[index] = 1; for(int j = 0; j < n; j++)//找出的新点会影响与它相邻的点到起始点的最小距离, 所以得修正一下 { if(Map[index][j].l != INF && !vis[j]) { if(dis[index] + Map[index][j].l < dis[j]) { dis[j] = dis[index] + Map[index][j].l; cost[j] = cost[index] + Map[index][j].p; } else if(dis[index] + Map[index][j].l == dis[j]) { if(cost[index] + Map[index][j].p < cost[j]) { cost[j] = cost[index] + Map[index][j].p; } } } } } printf("%d %d\n", dis[d], cost[d]);//输出 return 1; }