HDU 3790 最短路径问题(Dijkstra 迪杰斯特法最短路径算法)
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
刚学了弗洛伊德算法,没错,我知道它会超时,果然就超时了,然后就学学迪杰斯特法算法
1 #include<stdio.h> 2 #include<string.h> 3 #define inf 0x3fffffff 4 using namespace std; 5 int a,b,d,q,s,t,n,m; 6 int vis[1010]; 7 8 struct node{ 9 int dis,cost;//定义结构体,dis表示距离,cost表示花费 10 }route[1010][1010],dp[1010]; 11 12 void dijkstra(int s)//模板 13 { 14 int mark,min; 15 memset(vis,0,sizeof(vis));//初始化 16 for(int i=1;i<=n;i++){ 17 dp[i].dis=inf; 18 dp[i].cost=inf; 19 } 20 dp[s].dis=0; 21 dp[s].cost=0; 22 for(int i=1;i<=n;i++){ 23 min=inf;mark=-1; 24 for(int j=1;j<=n;j++){ 25 if(min>dp[j].dis&&vis[j]==0){//找到最短的路,并记录,下一次在剩下的路中找最短的路 26 mark=j; 27 min=dp[j].dis; 28 } 29 } 30 if(mark==-1) break;//如果没有最短的路了,就跳出,结束 31 vis[mark]=1;//把走过的路标记 32 for(int j=1;j<=n;j++){ //如果走的路程能变小,或路程不变,花费变小,就通过这条中间路 33 if(dp[j].dis>dp[mark].dis+route[mark][j].dis||(dp[j].dis==dp[mark].dis+route[mark][j].dis&&dp[j].cost>dp[mark].cost+route[mark][j].cost)){ 34 dp[j].dis=dp[mark].dis+route[mark][j].dis; 35 dp[j].cost=dp[mark].cost+route[mark][j].cost; 36 } 37 } 38 } 39 } 40 41 int main(){ 42 while(~scanf("%d%d",&n,&m)){ 43 if(n==0&&m==0) break; 44 for(int i=1;i<=n;i++){ 45 for(int j=1;j<=n;j++){ 46 route[i][j].dis=inf;//初始化为一个极大的值 47 route[i][j].cost=inf; 48 } 49 } 50 for(int i=0;i<m;i++){ 51 scanf("%d %d %d %d",&a,&b,&d,&q); 52 if(route[a][b].dis>d||(route[a][b].dis==d&&route[a][b].cost>q)){ 53 route[a][b].dis=route[b][a].dis=d; 54 route[a][b].cost=route[b][a].cost=q; 55 } 56 } 57 scanf("%d %d",&s,&t); 58 dijkstra(s); 59 printf("%d %d\n",dp[t].dis,dp[t].cost); 60 } 61 return 0; 62 }
(またお腹がすいた)
posted on 2019-01-01 09:45 甜甜圈不懂巧克力的苦 阅读(216) 评论(0) 编辑 收藏 举报