题意:。。。
难点:如何处理两个权值。
分析:题意说如果最短路径有多个,那么取价值最低的那个,所以说价值随着路径在变,如果路径不相等那么就更新路径并且更新价值,反之,则判断价值是不是要更新。
代码:
#include<stdio.h>
#include<string.h>
#define M 1002
#define INF 0x3f3f3f3f
int mapp[M][M], mapd[M][M], n, m, di[M], dp[M];//mapd是路径 mapp是价值
bool vis[M];
void dij(int v, int st)
{
int i, j, min, pos = v;
for(i = 1; i <= n; i++){
di[i] = mapd[v][i];
dp[i] = mapp[v][i];
vis[i] = 0;
}
vis[v] = 1;
di[i] = 0;
for(i = 1; i < n; i ++){
min = INF;
for(j = 1; j <= n; j ++){
if(!vis[j]&&di[j] < min){
min = di[j];
pos = j;
}
}
vis[pos] = 1;
for(j = 1; j <= n; j ++){
if(!vis[j]){
if(di[j] > di[pos]+mapd[pos][j]){ //首先判断路径要不要更新,如果要更新路径和价值
di[j] = di[pos]+mapd[pos][j];
dp[j] = dp[pos]+mapp[pos][j];
}
else if(di[j] == di[pos]+mapd[pos][j]){ //路径不用更新,在判断价值要不要更新
if(dp[j] > dp[pos]+mapp[pos][j]){
dp[j] = dp[pos]+mapp[pos][j];
}
}
}
}
}
printf("%d %d\n", di[st], dp[st]);
}
int main()
{
int i, j, a, b, d, p;
while(scanf("%d%d", &n, &m),n||m){
for(i = 1; i <= n; i ++){
for(j = 1; j <= n; j ++){
mapd[i][j] = mapp[i][j] = INF;
}
}
for(i = 0; i < m; i ++){
scanf("%d%d%d%d", &a, &b, &d, &p);
if(mapd[a][b]>d){
mapp[a][b] = mapp[b][a] = p;
mapd[a][b] = mapd[b][a] = d;
}
}
int st, en;
scanf("%d%d", &st, &en);
dij(en, st);
}
}
题目链接: 点击打开链接