题目描述
给你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;
}
} 
京公网安备 11010502036488号