题目描述
给你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)
输出
输出 一行有两个数, 最短距离及其花费。
样例输入
3 21 2 5 62 3 4 51 30 0
样例输出
9 11
解题思路:dijkstra模板变形,首先路径最短是优先级最高的,之后才是费用问题,只有当路径出现相等的时间才有价值问题的比较。
代码:
#include<stdio.h>
#include<string.h>
int a[1010][1010];
int b[1010][1010];
int dis[1010];
int meny[1010];
int f[1010];
int main()
{
int i,j,k,inf,c1,min,sum,x1,x2,x3,x4,m,n;
inf=99999999;
while(scanf("%d%d",&m,&n),m+n!=0)
{
for(i=1;i<=m;i++)
for(j=1;j<=m;j++)
if(i==j)
{
a[i][j]=0;
b[i][j]=0;
}
else
{
a[i][j]=inf;
b[i][j]=inf;
}
memset(f,0,sizeof(f));
for(i=0;i<n;i++)
{
scanf("%d%d%d%d",&x1,&x2,&x3,&x4);
if(a[x1][x2]>x3)
{
a[x1][x2]=x3;
a[x2][x1]=x3;
b[x1][x2]=x4;
b[x2][x1]=x4;
}
}
scanf("%d%d",&x1,&x2);
for(i=1;i<=m;i++)
{
dis[i]=a[x1][i];
meny[i]=b[x1][i];
}
f[x1]=1;
c1=1;
while(c1<m)
{
min=inf;
for(i=1;i<=m;i++)
{
if(min>dis[i]&&f[i]==0)
{
min=dis[i];j=i;
}
}
f[j]=1;
c1++;
for(k=1;k<=m;k++)
{
if(a[j][k]<inf)
{
if(f[k]==0&&dis[k]>=dis[j]+a[j][k])
{
if(dis[k]==dis[j]+a[j][k]&&meny[k]>meny[j]+b[j][k])
meny[k]=meny[j]+b[j][k];
if(dis[k]>dis[j]+a[j][k])
{
dis[k]=dis[j]+a[j][k];
meny[k]=meny[j]+b[j][k];
}
}
}
}
}
printf("%d %d\n",dis[x2],meny[x2]);
}
return 0;
}
#include<string.h>
int a[1010][1010];
int b[1010][1010];
int dis[1010];
int meny[1010];
int f[1010];
int main()
{
int i,j,k,inf,c1,min,sum,x1,x2,x3,x4,m,n;
inf=99999999;
while(scanf("%d%d",&m,&n),m+n!=0)
{
for(i=1;i<=m;i++)
for(j=1;j<=m;j++)
if(i==j)
{
a[i][j]=0;
b[i][j]=0;
}
else
{
a[i][j]=inf;
b[i][j]=inf;
}
memset(f,0,sizeof(f));
for(i=0;i<n;i++)
{
scanf("%d%d%d%d",&x1,&x2,&x3,&x4);
if(a[x1][x2]>x3)
{
a[x1][x2]=x3;
a[x2][x1]=x3;
b[x1][x2]=x4;
b[x2][x1]=x4;
}
}
scanf("%d%d",&x1,&x2);
for(i=1;i<=m;i++)
{
dis[i]=a[x1][i];
meny[i]=b[x1][i];
}
f[x1]=1;
c1=1;
while(c1<m)
{
min=inf;
for(i=1;i<=m;i++)
{
if(min>dis[i]&&f[i]==0)
{
min=dis[i];j=i;
}
}
f[j]=1;
c1++;
for(k=1;k<=m;k++)
{
if(a[j][k]<inf)
{
if(f[k]==0&&dis[k]>=dis[j]+a[j][k])
{
if(dis[k]==dis[j]+a[j][k]&&meny[k]>meny[j]+b[j][k])
meny[k]=meny[j]+b[j][k];
if(dis[k]>dis[j]+a[j][k])
{
dis[k]=dis[j]+a[j][k];
meny[k]=meny[j]+b[j][k];
}
}
}
}
}
printf("%d %d\n",dis[x2],meny[x2]);
}
return 0;
}