hdoj最短路径问题

来源:互联网 发布:jar软件下载平台 编辑:程序博客网 时间:2024/05/16 05:41

最短路径问题

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 17994    Accepted Submission(s): 5398


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 21 2 5 62 3 4 51 30 0
 


 

Sample Output
9 11
 


 

Source
浙大计算机研究生复试上机考试-2010年
本题考查最短路径问题,最好用万能的dijkstra,好写不超时,floyd算法更好写,但往往数据一大就超时,时间复杂度为o(n^3),所以就用dijkstra,具体讲解在代码里。
#include<stdio.h>#include<string.h>#define M 9000000int n,m,a,b,c,d,s[1001][1001],s1[1001][1001],s2[1001],s3[1001];//两个二维数组分别存放各个两点之间长度和花费,两个一维数组分别存放二维数组每一行bool s4[1001];void dij(int x,int y){int pt,i,min,min1;memset(s4,false,sizeof(s4));memset(s2,M,sizeof(s2));memset(s3,M,sizeof(s3));//前面都是初始化pt=x;s4[pt]=true;s2[pt]=0;s3[pt]=0;while(true){if(pt==y)break;for(i=1;i<=n;i++){if(s2[i]>s2[pt]+s[pt][i])//先比较路径{s2[i]=s2[pt]+s[pt][i];s3[i]=s3[pt]+s1[pt][i];}else if(s2[i]==s2[pt]+s[pt][i])//如果相等就比较经费{if(s3[i]>s3[pt]+s1[pt][i]){s2[i]=s2[pt]+s[pt][i];s3[i]=s3[pt]+s1[pt][i];}}}s4[pt]=true;min=100000;min1=100000;for(i=1;i<=n;i++)if(!s4[i]){if(min>s2[i])//和上面思想相同{min=s2[i];min1=s3[i];pt=i;}else if(min==s2[i]){if(min1>s3[i]){min=s2[i];min1=s3[i];pt=i;}}}}}int main(){while(scanf("%d%d",&n,&m)&&(n+m)){memset(s,M,sizeof(s));memset(s1,M,sizeof(s1));while(m--){scanf("%d%d%d%d",&a,&b,&c,&d);if(c<s[a][b]){s[a][b]=c;s[b][a]=c;s1[a][b]=d;s1[b][a]=d;}}scanf("%d%d",&a,&b);dij(a,b);printf("%d %d\n",s2[b],s3[b]);}return 0;}

 


 

0 0