最短路径问题
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 15296 Accepted Submission(s): 4629
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<cstdlib> #include<cstring> #define inf 0x3f3f3f3f using namespace std; int map[2][1010][1010],vis[1010],dis[2][1010]; int n,m,s,t; int getnext(){ int i,u=-1,t=inf; int temp=inf; for(i=1;i<=n;++i){ if(!vis[i]&&(dis[0][i]<temp||(dis[0][i]==temp&&dis[1][i]<t))){ t=dis[1][i];temp=dis[0][i]; u=i; } } return u; } void dijkstra(){ int u=s,temp,i,j,k; memset(vis,0,sizeof(vis)); while(u!=-1){ for(i=1;i<=n;++i){ temp=dis[0][u]+map[0][u][i]; if(temp<dis[0][i]){ dis[0][i]=temp; dis[1][i]=dis[1][u]+map[1][u][i]; } else if(temp==dis[0][i]){ if(dis[1][u]+map[1][u][i]<dis[1][i]){ dis[1][i]=dis[1][u]+map[1][u][i]; } } } vis[u]=1; if(u==t){ printf("%d %d\n",dis[0][t],dis[1][t]); break; } u=getnext(); } } int main() { int i,j,a,b,c,d; while(scanf("%d%d",&n,&m)!=EOF){ if(n==0&&m==0)break; memset(dis,0x3f,sizeof(dis)); memset(map,0x3f,sizeof(map)); for(j=0;j<m;++j){ scanf("%d%d%d%d",&a,&b,&c,&d); if(c<map[0][a][b]||(map[0][a][b]==c&&map[1][a][b]>d)){ map[0][a][b]=map[0][b][a]=c; map[1][a][b]=map[1][b][a]=d; } } scanf("%d%d",&s,&t); dis[0][s]=dis[1][s]=0; dijkstra(); } return 0; }
时间: 2024-10-31 10:38:15