题目描述
给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
输入描述
输入n,m 点的编号是1-n,共m条边。 然后是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 <iostream> using namespace std; #define INF 0x3f3f3f3f #define N 1001 int disGraph[N][N];//距离图 int costGraph[N][N];//花费图 int dist[N];//原点到各点距离 int cost[N];//源点到各点花费 bool collected[N];//是否被收录集合 int n, m; void init(int n) //初始化 { for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { disGraph[i][j] = i == j ? 0 : INF; //对角线为0,其余为无穷大 costGraph[i][j] = i == j ? 0 : INF; } dist[i] = INF; cost[i] = INF; collected[i] = false; } } void makeGraph(int m)//生成距离图和花费图 { int tmpNode1, tmpNode2, tmpDis, tmpCost; for (int i = 0; i < m; i++)//读取m条边的距离及花费 { cin >> tmpNode1 >> tmpNode2 >> tmpDis >> tmpCost; if (disGraph[tmpNode1][tmpNode2] > tmpDis) //距离更短,则不计花费,更新距离 { disGraph[tmpNode1][tmpNode2] = tmpDis; disGraph[tmpNode2][tmpNode1] = tmpDis; costGraph[tmpNode1][tmpNode2] = tmpCost; costGraph[tmpNode2][tmpNode1] = tmpCost; } else if (disGraph[tmpNode1][tmpNode2] == tmpDis && costGraph[tmpNode1][tmpNode2] > tmpCost)//距离相等,花费更少,则更新花费 { costGraph[tmpNode1][tmpNode2] = tmpCost; costGraph[tmpNode2][tmpNode1] = tmpCost; } } } int FindMinDist() { int MinV; int MinDist = INF; for (int i = 1; i <= n; i++) { if (collected[i] == false && dist[i] < MinDist) //在未收录的点中找到最小的路径 { MinDist = dist[i]; MinV = i; } } if (MinDist < INF) return MinV; else return -1; } void Dijkstra(int s) { dist[s] = 0; //原点到自身距离设置为0 cost[s] = 0; //原点到自身的花费设置为0 collected[s] = true; //将原点自身收录 for (int i = 1; i <= n; i++) { if (disGraph[s][i] != INF) //如果s到i可达,设置dist中s到i的距离及花费 { dist[i] = disGraph[s][i]; //相邻点距离设置为边长 cost[i] = costGraph[s][i]; //设置相邻点的花费 } } int V;//V为未收录的最短路径点 while (1) { V = FindMinDist(); if (V == -1) break; collected[V] = true; for (int i = 1; i <= n; i++)//遍历V的所有临接点 { if (collected[i] == false && disGraph[V][i] < INF) { if (dist[V] + disGraph[V][i] < dist[i])//路径更短 { dist[i] = dist[V] + disGraph[V][i];//更新最短路径表 cost[i] = cost[V] + costGraph[V][i];//更新最短路径所需花费 } else if (dist[V] + disGraph[V][i] == dist[i] && cost[V] + costGraph[V][i] < cost[i])//花费更少 cost[i] = cost[V] + costGraph[V][i];//更新所需花费 } } } } int main() { while (cin >> n >> m) { if (n == 0 && m == 0) break; init(n); makeGraph(m); int s, t; cin >> s >> t; Dijkstra(s); cout << dist[t] << ' ' << cost[t] << endl; } }