Problem Description
给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
Input
输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点。n和m为0时输入结束。
(1 < n<=1000, 0< m<100000, s != t)
Output
输出 一行有两个数, 最短距离及其花费。
Sample Input
3 2
1 2 5 6
2 3 4 5
1 3
0 0
Sample Output
9 11
注意重边;
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=0xfffffff;
struct node{
int l,w;
}map[1005][1005],d[1005];
int vis[1005];
int main()
{
int n,m;
while(scanf("%d%d",&n,&m),n||m)
{
memset(map,-1,sizeof(map));
memset(vis,0,sizeof(vis));
for(int i=1;i<=m;i++)
{
int a,b,l,w;
scanf("%d%d%d%d",&a,&b,&l,&w);
if(map[a][b].l!=-1)
{
if(l<map[a][b].l||(l==map[a][b].l&&w<map[a][b].w))
{
map[a][b].l=l;
map[a][b].w=w;
map[b][a].l=l;
map[b][a].w=w;
}
continue;
}
map[a][b].l=l;
map[a][b].w=w;
map[b][a].l=l;
map[b][a].w=w;
}
int start,end;
scanf("%d%d",&start,&end);
for(int i=1;i<=n;i++)
if(map[start][i].l!=-1)
{
d[i].l=map[start][i].l;
d[i].w=map[start][i].w;
}
else
d[i].l=d[i].w=maxn;
vis[start]=1;
for(int i=1;i<n;i++)
{
int minn=maxn;
int minx=maxn;
int k;
for(int j=1;j<=n;j++)
if(!vis[j]&&(d[j].l<minn||(d[j].l==minn&&d[j].w<minx)))
{
minn=d[j].l;
minx=d[j].w;
k=j;
}
vis[k]=1;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&map[k][j].l!=-1&&((d[j].l>d[k].l+map[k][j].l)||((d[j].l==d[k].l+map[k][j].l)&&(d[j].w>d[k].w+map[k][j].w))))
{
d[j].l=d[k].l+map[k][j].l;
d[j].w=d[k].w+map[k][j].w;
}
}
}
printf("%d %d\n",d[end].l,d[end].w);
}
}