题目链接:点击打开链接
带两种权值的最短路问题,用dijkstra松弛和找离源点最近的点都需要考虑两种权值,具体看代码实现。
坑是输入中两个点间不一定只有一条边!wa了好几次。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int a[1010][1010];
bool vis[1010];
int c[1010][1010];
int dis[1010];
int cost[1010];
int n,m;
inline void relax(int j,int k){
if(dis[j]>dis[k]+a[k][j]||(dis[j]==dis[k]+a[k][j]&&cost[j]>cost[k]+c[k][j])){
dis[j]=dis[k]+a[k][j];
cost[j]=cost[k]+c[k][j];
}
}
inline void dijkstra(int src){
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++){
dis[i]=a[src][i];
cost[i]=c[src][i];
}
vis[src]=1;
for(int i=1;i<n;i++){
int tmpt=100000000,tmpc=100000000,k=src;
for(int j=1;j<=n;j++){
if(vis[j])continue;
if(tmpt>dis[j]||(tmpt==dis[j]&&tmpc>cost[j])){
tmpt=dis[j];
tmpc=cost[j];
k=j;
}
}
vis[k]=1;
for(int j=1;j<=n;j++){
if(vis[j])continue;
relax(j,k);
}
}
}
int main(){
int x,y,d,p;
scanf("%d%d",&n,&m);
while(n||m){
memset(a,0x7f,sizeof(a));
memset(c,0x7f,sizeof(c));
for(int i=1;i<=n;i++){
a[i][i]=0;
c[i][i]=0;
}
for(int i=1;i<=m;i++){
scanf("%d%d%d%d",&x,&y,&d,&p);
if(a[x][y]>d||(a[x][y]==d&&c[x][y]>p)){
a[x][y]=a[y][x]=d;
c[x][y]=c[y][x]=p;
}
}
int s,t;
scanf("%d%d",&s,&t);
dijkstra(s);
printf("%d %d\n",dis[t],cost[t]);
scanf("%d%d",&n,&m);
}
return 0;
}
代码: