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
题目解析:多一重权值,就加一重“dis数组”。
代码如下:
1 # include<iostream> 2 # include<cstdio> 3 # include<cstring> 4 # include<algorithm> 5 # include<queue> 6 using namespace std; 7 const int INF=1<<29; 8 struct node 9 { 10 int v,l; 11 }; 12 node mp[1005][1005]; 13 int n,m,s,t; 14 int dis[1005],val[1005]; 15 void spfa() 16 { 17 fill(dis,dis+n+1,INF); 18 fill(val,val+n+1,INF); 19 queue<int>q; 20 q.push(s); 21 dis[s]=val[s]=0; 22 while(!q.empty()) 23 { 24 int u=q.front(); 25 q.pop(); 26 for(int i=1;i<=n;++i){ 27 if(dis[i]>dis[u]+mp[u][i].l){ 28 dis[i]=dis[u]+mp[u][i].l; 29 val[i]=val[u]+mp[u][i].v; 30 q.push(i); 31 }else if(dis[i]==dis[u]+mp[u][i].l&&val[i]>val[u]+mp[u][i].v){ 32 val[i]=val[u]+mp[u][i].v; 33 q.push(i); 34 } 35 } 36 } 37 printf("%d %d\n",dis[t],val[t]); 38 } 39 void init() 40 { 41 for(int i=1;i<=n;++i) 42 for(int j=1;j<=n;++j) 43 mp[i][j].l=mp[i][j].v=(i==j)?0:INF; 44 } 45 int main() 46 { 47 int a,b,c,d; 48 while(scanf("%d%d",&n,&m),n+m) 49 { 50 init(); 51 while(m--) 52 { 53 scanf("%d%d%d%d",&a,&b,&c,&d); 54 if(mp[a][b].l>c){ 55 mp[a][b].l=mp[b][a].l=c; 56 mp[a][b].v=mp[b][a].v=d; 57 }else if(mp[a][b].l==c){ 58 mp[a][b].v=mp[b][a].v=min(d,mp[a][b].v); 59 } 60 } 61 scanf("%d%d",&s,&t); 62 spfa(); 63 } 64 return 0; 65 }
时间: 2024-11-09 02:41:59