HDU 3790 最短路径问题
最短路径问题
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 32989 Accepted Submission(s): 9689
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
最短路的模板题,需要注意的是在路径c长度相同时应选择最小花费的那一条
#include <stdio.h> #include <algorithm> #include <string.h> using namespace std; #define INF 0x3f3f3f3f #define maxn 2005 int cost[maxn][maxn],lowcost[maxn],pre[maxn],cost1[maxn][maxn],lowcost1[maxn]; bool vis[maxn]; int n,m; void dijkstra(int n,int beg) { for(int i=1; i<=n; i++) { lowcost[i]=INF; lowcost1[i]=INF; vis[i]=false; pre[i]=-1; } lowcost[beg]=0; lowcost1[beg]=0; for(int i=1; i<=n; i++) { int k=0; int minn=INF; for(int j=1; j<=n; j++) { if(!vis[j]&&lowcost[j]<minn) { minn=lowcost[j]; k=j; } } if(k==-1) { break; } vis[k]=true; for(int j=1;j<=n;j++) { if(!vis[j]&&lowcost[k]+cost[k][j]<lowcost[j]) { lowcost[j]=lowcost[k]+cost[k][j]; lowcost1[j]=lowcost1[k]+cost1[k][j]; pre[j]=k; } else if(!vis[j]&&lowcost[k]+cost[k][j]==lowcost[j]) { if(lowcost1[j]>lowcost1[k]+cost1[k][j]) { lowcost1[j]=lowcost1[k]+cost1[k][j]; } } } } return ; } int main() { int n,m; while(~scanf("%d%d",&n,&m)&&(m+n)) { for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { cost[i][j]=INF; cost1[i][j]=INF; } } for(int i=1; i<=m; i++) { int a,b,c,d; scanf("%d%d%d%d",&a,&b,&c,&d); if(c<cost[a][b]) { cost[a][b]=c; cost[b][a]=c; cost1[a][b]=d; cost1[b][a]=d; } } int x,y; scanf("%d%d",&x,&y); dijkstra(n,x); printf("%d %d\n",lowcost[y],lowcost1[y]); } return 0; }