最短路径问题Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 16300 Accepted Submission(s): 4898 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
迪杰斯特拉算法 :比一般模版多加了一个条件,只要在每次添加顶点的时候,同时要考虑变得value,那么也就是说要添加在一次遍历中长度最小&&value最小的那条边。然后更新另一个划分界点中到源点的最短距离。
其实感觉和克鲁斯卡尔算法思路一样啊~~
#include<stdio.h> #include<string.h> const int M=0x1f1f1f1f; const int INF=1003; int cost[INF][INF]; int dis[INF][INF]; int lowdis[INF]; int lowcost[INF]; int flag[INF]; int n,m; void dij(int n,int s,int e) { flag[s]=1; for(int i=1; i<=n; i++)//相当于算法的初始化阶段 { lowdis[i]=dis[s][i]; lowcost[i]=cost[s][i] ; } for(int i=1; i<n; i++) { int loc, Mindis,Mincost; Mindis=Mincost=M; for(int j =1; j<=n; j++)//每次找出安全点加入 { if(flag[j]==0) { if(lowdis[j]<Mindis)//长度优先 { Mindis=lowdis[j]; Mincost=lowcost[j]; loc=j; } else if(lowdis[j]==Mindis&&lowcost[j]<Mincost)//如果长度相同则要考虑加入价值较小的 { Mindis=lowdis[j]; Mincost=lowcost[j]; loc=j; } } } // cout<<"loc="<<loc<<endl; flag[loc]=1; if(loc==e) // 如果末点到原点间的距离已经算出,那么break; break; for(int i=1; i<=n; i++) { if(!flag[i]) { if(dis[loc][i]+lowdis[loc]<lowdis[i])//还是长度为主要考虑因素,如果长度比原来最短路径要小那么一定更新。 { lowdis[i]=dis[loc][i]+lowdis[loc]; lowcost[i]=cost[loc][i]+lowcost[loc]; } else if(dis[loc][i]+lowdis[loc]==lowdis[i]&&cost[loc][i]+lowcost[loc]<lowcost[i])//如果发现更新和不更新长度想等,此时就要判断价值小的那条路然后确定更不更新。 { lowdis[i]=lowdis[loc]+dis[loc][i]; lowcost[i]=lowcost[loc]+cost[loc][i]; } } } } } int main() { while(scanf("%d%d",&n,&m),n+m) { memset(cost,0x1f,sizeof(cost)); memset(dis,0x1f,sizeof(dis)); memset(flag,0,sizeof(flag)); for(int i=1; i<=n; i++) { cost[i][i]=0; dis[i][i]=0; } for(int i=0; i<m; i++) { int a,b,d,p; scanf("%d%d%d%d",&a,&b,&d,&p); if(dis[a][b]>d||(dis[a][b]==d&&cost[a][b]>p))//要我根本想不到会有重边。 { dis[a][b]=dis[b][a]=d; cost[a][b]=cost[b][a]=p; } } int s , t; scanf("%d%d",&s,&t); dij(n,s,t); printf("%d %d\n",lowdis[t],lowcost[t]); } return 0; } |
原文地址:http://blog.csdn.net/lsgqjh/article/details/46308677