最短路径问题
Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
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)
(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 <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <queue> #include <vector> #include <iomanip> #include <math.h> #include <map> using namespace std; #define FIN freopen("input.txt","r",stdin); #define FOUT freopen("output.txt","w",stdout); #define INF 0x3f3f3f3f #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 typedef long long LL; const int MAXN=1000+5; int Map[MAXN][MAXN]; int dis[MAXN]; int vis[MAXN]; int cost[MAXN][MAXN]; int c[MAXN]; int n,m; int llss(int s,int e){ for(int i=1;i<=n;i++){ dis[i]=Map[s][i]; c[i]=cost[s][i]; } memset(vis,0,sizeof(vis)); vis[s]=1; dis[s]=0; c[s]=0; int temp,k; for(int i=1;i<=n;i++){ if(vis[e]) break; temp=INF; for(int j=1;j<=n;j++){ if(!vis[j]&&temp>dis[j]){ k=j; temp=dis[j]; } } if(temp==INF) break; vis[k]=1; for(int j=1;j<=n;j++){ if(!vis[j]&&Map[k][j]<INF){ if(dis[j]>dis[k]+Map[k][j]){ dis[j]=dis[k]+Map[k][j]; c[j]=c[k]+cost[k][j]; } else if(dis[j]==dis[k]+Map[k][j]){ if(c[j]>c[k]+cost[k][j]) c[j]=c[k]+cost[k][j]; } } } } printf("%d %d ",dis[e],c[e]); } int main() { //FIN int st,ed,len,cos; int s,e; while(~scanf("%d%d",&n,&m)) { if(n==0&&m==0) break; memset(Map,INF,sizeof(Map)); memset(cost,INF,sizeof(cost)); for(int i=1;i<=n;i++){ Map[i][i]=0; cost[i][i]=0; } for(int i=1;i<=m;i++){ scanf("%d%d%d%d",&st,&ed,&len,&cos); if(Map[st][ed]>len){ Map[st][ed]=Map[ed][st]=len; cost[st][ed]=cost[ed][st]=cos; } else if(Map[st][ed]==len){ if(cost[st][ed]>cos) cost[st][ed]=cost[ed][st]=cos; } } scanf("%d%d",&s,&e); llss(s,e); } }