题目思路:
这题并不难,分清楚优先级就行,仍是求最短路径,但是在松弛的时候,如果 dis[j] == dis[p] + map[p][j] 那么松弛就需要变成求花费更少的路径。这里鄙人开了两个dis数组,两个map数组,一个vis数组......
Dijkstra写法
#include<cstdio>
#include<algorithm>
#define maxn 1005
#define INF 0x3f3f3f3f
using namespace std;
int n,m;
int map[maxn][maxn],mapc[maxn][maxn];
int dis[maxn],disc[maxn];
bool vis[maxn];
void Init(){
for(int i = 1; i <= n; i++){
vis[i] = 0;
dis[i] = INF;
disc[i] = INF;
for(int j = 1; j < i; j++){
map[i][j] = map[j][i] = INF;
mapc[i][j] = mapc[j][i] = INF;
}
}
}
void Dijkstra(int s){
dis[s] = disc[s] = 0;
for(int i = 1; i <= n; i++){
int p = s , minn = INF;
for(int j = 1; j <= n; j++){
if(!vis[j] && minn > dis[j]){
p = j;
minn = dis[j];
}
}
vis[p] = 1;
for(int j = 1; j <= n; j++){
if(!vis[j]){
if(dis[j] == dis[p] + map[p][j])
disc[j] = min(disc[j],disc[p] + mapc[p][j]);
else if(dis[j] > dis[p] + map[p][j]){
dis[j] = dis[p] + map[p][j];
disc[j] = disc[p] + mapc[p][j];
}
}
}
}
}
int main(){
int a,b,d,p,s,t;
while(~scanf("%d%d",&n,&m),n+m){
Init();
for(int i = 1; i <= m; i++){
scanf("%d%d%d%d",&a,&b,&d,&p);
if(map[a][b] > d){
map[a][b] = map[b][a] = d;
mapc[a][b] = mapc[b][a] = p;
}
else if(map[a][b] == d && mapc[a][b] > p)
mapc[a][b] = mapc[b][a] = p;
}
scanf("%d%d",&s,&t);
Dijkstra(s);
printf("%d %d\n",dis[t],disc[t]);
}
return 0;
}