题目描述
给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
输入描述:
输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点t。n和m为0时输入结束。 (1<n<=1000, 0<m<100000, s != t)
输出描述:
输出 一行有两个数, 最短距离及其花费。
示例1
输入
3 2 1 2 5 6 2 3 4 5 1 3
输出
9 11
代码如下:(一定要注意)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N 1005
#define MAX 0x3f3f3f3f
int map[N][N],f[N][N],dis[N],path[N],fee[N],vis[N];
void dijkstra(int s,int t,int n){
int i,j,v;
v=s;
dis[s]=fee[s]=0; vis[s]=1; path[s]=s;
for(i=1;i<=n;i++)
if(!vis[i]&&map[s][i]!=MAX){
dis[i]=map[s][i];
fee[i]=f[s][i];
path[i]=s;
}
for(i=0;i<n-1;i++){
int min=MAX;
for(j=1;j<=n;j++)
if(!vis[j]&&dis[j]<min){
min=dis[j];
v=j;
}
if(min==MAX)
break;
vis[v]=1;
for(j=1;j<=n;j++)
if(!vis[j]&&map[v][j]!=MAX){
if(dis[j]>dis[v]+map[v][j]){
dis[j]=dis[v]+map[v][j];
fee[j]=fee[v]+f[v][j];
path[j]=v;
}else if(dis[j]==dis[v]+map[v][j]&&fee[j]>fee[v]+f[v][j]){
fee[j]=fee[v]+f[v][j];
path[j]=v;
}
}
}
printf("%d %d\n",dis[t],fee[t]);
}
int main(){
int n,m,a,b,d,p,s,t,i,j;
while(scanf("%d %d",&n,&m)!=EOF){
if(n==0&&m==0)
break;
for(i=1;i<=n;i++){
for(j=1;j<=n;j++)
map[i][j]=f[i][j]=MAX;
dis[i]=fee[i]=MAX;
vis[i]=0;
path[i]=-1;
}
while(m--){
scanf("%d %d %d %d",&a,&b,&d,&p);
if(map[a][b]>d){
map[a][b]=map[b][a]=d;
f[a][b]=f[b][a]=p;
}else if(map[a][b]==d&&f[a][b]>p)
f[a][b]=f[b][a]=p;
}
scanf("%d %d",&s,&t);
dijkstra(s,t,n);
}
return 0;
}
额外测试数据:
//测试数据
2 2
1 2 5 10
2 1 4 12
1 2
4 12
4 4
1 2 5 6
2 3 4 5
1 4 5 10
4 3 4 2
1 3
9 11
6 7
1 2 5 6
1 3 5 1
2 6 2 1
3 4 1 1
4 2 1 1
4 5 1 1
5 2 3 1
5 6
4 3