描述
题解
虽然是最短路,但是有坑,首先题目中没有提到重边问题,这里需要先判断重边,去除重边,接着,要求,满足路径最短的情况下花费最小,一开始是先求最短路,然后把最短路上的花费累加起来,后来发现,这是错误的,因为有可能存在最短路不止一条,所以需要求最小的花费,所以,不能把这两部分分开求,需要一起搞~~~还是模版,毕竟周星星是一本漫画走天下,而我是一本模版玩ACM……
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
/* * 单源最短路径,dijkstra算法,邻接矩阵形式,复杂度为O(n^2) * 两点间距离存入map[][],两点间花费存入cost[][] * 求出源st到所有点的最短路径及其对应最小花费 * 返回各点的最短路径lowdis[]以及对应的最小花费lowval[] * 可更改路径权类型,但是权值必须为非负 */
const int MAXN = 1010;
const int INF = 0x3f3f3f3f;
int n, m;
int lowdis[MAXN];
int lowval[MAXN];
int visit[MAXN];
int map[MAXN][MAXN];
int cost[MAXN][MAXN];
void dijkstra(int st)
{
int temp = 0;
for (int i = 1; i <= n; i++)
{
lowdis[i] = map[st][i];
lowval[i] = cost[st][i];
}
memset(visit, 0, sizeof(visit));
visit[st] = 1;
for (int i = 1; i < n; i++)
{
int MIN = INF;
for (int j = 1; j <= n; j++)
{
if (!visit[j] && lowdis[j] < MIN)
{
temp = j;
MIN = lowdis[j];
}
}
visit[temp] = 1;
for (int j = 1; j <= n; j++)
{
if (!visit[j] && map[temp][j] < INF)
{
if (lowdis[j] > lowdis[temp] + map[temp][j])
{
lowdis[j] = lowdis[temp] + map[temp][j];
lowval[j] = lowval[temp] + cost[temp][j];
}
else if (lowdis[j] == lowdis[temp] + map[temp][j])
{
if (lowval[j] > lowval[temp] + cost[temp][j])
{
lowval[j] = lowval[temp] + cost[temp][j];
}
}
}
}
}
return ;
}
int main()
{
int st, ed;
int a, b, c, d;
while (scanf("%d%d", &n, &m), n || m)
{
memset(map, 0x3f, sizeof(map));
memset(cost, 0x3f, sizeof(map));
while (m--)
{
scanf("%d%d%d%d", &a, &b, &c, &d);
// 判断重边
if (map[a][b] > c)
{
map[a][b] = map[b][a] = c;
cost[a][b] = cost[b][a] = d;
}
else if (map[a][b] == c)
{
if (cost[a][b] > d)
{
cost[a][b] = cost[b][a] = d;
}
}
}
scanf("%d%d", &st, &ed);
dijkstra(st);
printf("%d %d\n", lowdis[ed], lowval[ed]);
}
return 0;
}