前言:
本题是对Dijkstra算法的利用,多了一个算最小的花费
关键点:
1、首先是初始化,所有的G(存道路的距离),F(存花费), dist(存最短距离), mincost(存最短花费), 都设为最大值,且当前点到自己的距离和花费置为0
for (int i=0; i<n; i++)
{
dist[i] = INF;
mincost[i] = INF;
for (int j=0; j<n; j++)
{
if (i==j)
{
G[i][j] = 0;
F[i][j] = 0;
}
else
{
G[i][j] = INF;
F[i][j] =INF;
}
}
}
2、如何加入算最小的花费?
在判断最小距离的同时,当最小距离和当前距离相同时,加上最小花费的判断,若当前距离小于最小距离,那么直接更新花费(因为优先级是先在距离最小的前提下,再来考虑花费)
for (int i=0; i<n; i++)
{
if (!collected[i]&&dist[k]+G[k][i]<=dist[i])
{
if (dist[k]+G[k][i]<dist[i])
{
dist[i] = dist[k]+G[k][i];
mincost[i] = mincost[k]+F[k][i];
}
else
{
if (mincost[k]+F[k][i]<mincost[i])
mincost[i] = mincost[k]+F[k][i];
}
}
}
完整代码:
# include<stdio.h>
# define MAX 600
# define INF 100000
int G[MAX][MAX];
int F[MAX][MAX];
int dist[MAX];
int mincost[MAX];
int collected[MAX];
int n, m, s, d;
void Dijkstra()
{
for (int i=0; i<n; i++)
{
if (G[s][i]<INF)
{
dist[i] = G[s][i];
mincost[i] = F[s][i];
}
collected[i] = 0;
}
dist[s] = 0;
mincost[s] = 0;
collected[s] = 1;
while (1)
{
int k;
int Min = INF;
for (int i=0; i<n; i++)
{
if (!collected[i]&&dist[i]<Min)
{
Min = dist[i];
k = i;
}
}
if (Min==INF)
break;
collected[k] = 1;
for (int i=0; i<n; i++)
{
if (!collected[i]&&dist[k]+G[k][i]<=dist[i])
{
if (dist[k]+G[k][i]<dist[i])
{
dist[i] = dist[k]+G[k][i];
mincost[i] = mincost[k]+F[k][i];
}
else
{
if (mincost[k]+F[k][i]<mincost[i])
mincost[i] = mincost[k]+F[k][i];
}
}
}
}
}
int main()
{
scanf("%d%d%d%d", &n, &m, &s, &d);
for (int i=0; i<n; i++)
{
dist[i] = INF;
mincost[i] = INF;
for (int j=0; j<n; j++)
{
if (i==j)
{
G[i][j] = 0;
F[i][j] = 0;
}
else
{
G[i][j] = INF;
F[i][j] =INF;
}
}
}
for (int i=0; i<m; i++)
{
int x1, x2, len, cost;
scanf("%d%d%d%d", &x1, &x2, &len, &cost);
G[x1][x2] = len;
G[x2][x1] = len;
F[x1][x2] = cost;
F[x2][x1] = cost;
}
Dijkstra();
printf("%d %d\n", dist[d], mincost[d]);
return 0;
}