Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 20537 Accepted Submission(s): 6091
http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html
Total Submission(s): 20537 Accepted Submission(s): 6091
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)
(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
//今天新学的最短路,A了一道模板题
//http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html这个大神写的不错,从这里学的
#include<stdio.h> #include<string.h> #include<algorithm> #define inf 0x3f3f3f3f//这个当做无穷大,因为这样无穷大+无穷大不会爆 using namespace std; int a[1005][1005],b[1005][1005],vis[1005],dis[1055],time[1005],n,m; void dijkstra(int x,int y) { memset(dis,inf,sizeof(dis)); memset(time,inf,sizeof(time)); memset(vis,0,sizeof(vis)); for(int i=1; i<=n; i++)//写出起点能到达的点 { dis[i]=a[x][i]; time[i]=b[x][i]; } vis[x]=1; while(1) { int min=inf,ok=-1; for(int i=1; i<=n; i++) { if(min>dis[i]&&vis[i]==0) { min=dis[i]; ok=i; } } vis[ok]=1; if(ok==-1) break; for(int j=1; j<=n; j++) { if(a[ok][j]!=inf&&dis[j]>dis[ok]+a[ok][j]) { dis[j]=dis[ok]+a[ok][j]; time[j]=time[ok]+b[ok][j]; } else if(a[ok][j]!=inf&&dis[j]==dis[ok]+a[ok][j])//如果路径相同,选最小的消耗值 { dis[j]=dis[ok]+a[ok][j]; time[j]=time[ok]+b[ok][j]; } } } return ; } int main() { int s1,e1,ju,s,s2,e2; while(~scanf("%d%d",&n,&m)) { memset(a,inf,sizeof(a)); memset(b,inf,sizeof(b)); if(n==0&&m==0) break; for(int i=1; i<=m; i++) { scanf("%d%d%d%d",&s1,&e1,&ju,&s); if(ju<a[s1][e1]) { a[s1][e1]=a[e1][s1]=ju; b[s1][e1]=b[e1][s1]=s; } } scanf("%d%d",&s2,&e2); dijkstra(s2,e2); printf("%d %d\n",dis[e2],time[e2]); } }