HDU 3790 最短路径问题【多关键字最短路,Dijkstra算法+spfa算法】
2016-07-26 15:33
405 查看
最短路径问题
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 22410 Accepted Submission(s): 6688
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
Source
浙大计算机研究生复试上机考试-2010年
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=3790
注意:最短路径长度相同的时候要输出花费最少的,松弛操作的时候要注意。
要注意此题有重边!!cin TLE
Dijkstra 算法AC代码:
#include <iostream> #include <cstdio> using namespace std; int a[1005][1005]; int b[1005][1005]; int dis[1005]; int pay[1005]; bool vis[1005]; const int INF=0x3f3f3f3f; int n,m,s,t; void Dij() { for(int i=1; i<=n; i++) { dis[i]=a[s][i]; pay[i]=b[s][i]; vis[i]=false; } vis[s]=true; dis[s]=pay[s]=0; for(int i=1; i<=n; i++) { int minn=INF; int p; for(int j=1; j<=n; j++) { if(!vis[j]&&(dis[j]<minn)) { minn=dis[p=j]; } } vis[p]=true; if(minn==INF) break; for(int j=1; j<=n; j++) { if(!vis[j]&&a[p][j]!=INF) { int t=dis[p]+a[p][j]; if(t<dis[j]) { dis[j]=t; pay[j]=pay[p]+b[p][j]; } else if(t==dis[j]&&pay[p]+b[p][j]<pay[j]) { pay[j]=pay[p]+b[p][j]; } } } } } int main() { while(scanf("%d%d",&n,&m)!=EOF,n,m) { for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) if(i==j) a[i][j]=b[i][j]=0; else a[i][j]=b[i][j]=INF; } int x,y,z,zz; while(m--) { scanf("%d%d%d%d",&x,&y,&z,&zz); if(z<a[x][y]) { a[x][y]=a[y][x]=z; b[x][y]=b[y][x]=zz; } } cin>>s>>t; Dij(); cout<<dis[t]<<" "<<pay[t]<<endl; } return 0; }
spfa算法AC代码:
#include <cstdio> #include <queue> using namespace std; int a[1005][1005]; int b[1005][1005]; int dis[1005]; int pay[1005]; bool vis[1005]; int n,m,s,t; const int INF=0x3f3f3f3f; void spfa() { for(int i=1;i<=n;i++) { dis[i]=INF; pay[i]=INF; vis[i]=false; } vis[s]=true; dis[s]=pay[s]=0; queue<int>q; q.push(s); vis[s]=true; while(!q.empty()) { int now=q.front(); q.pop(); vis[now]=false; for(int i=1;i<=n;i++) { int d=dis[now]+a[now][i]; if(d<dis[i]) { dis[i]=d; pay[i]=pay[now]+b[now][i]; if(!vis[i]) { vis[i]=true; q.push(i); } } else if(d==dis[i]&&pay[now]+b[now][i]<pay[i]) { pay[i]=pay[now]+b[now][i]; if(!vis[i]) { vis[i]=true; q.push(i); } } } } } int main() { while(scanf("%d%d",&n,&m)!=EOF,n,m) { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) if(i==j) a[i][j]=b[i][j]=0; else a[i][j]=b[i][j]=INF; } int x,y,z,zz; while(m--) { scanf("%d%d%d%d",&x,&y,&z,&zz); if(a[x][y]>z) { a[x][y]=a[y][x]=z; b[x][y]=b[y][x]=zz; } } scanf("%d%d",&s,&t); spfa(); printf("%d %d\n",dis[t],pay[t]); } return 0; }
相关文章推荐
- Spring-data-jpa详解,全方位介绍。
- python,django安装
- I.MX6 MAC Address 导致的系统崩溃
- retrofit 完整教程
- Errors were encountered while processing:
- URI和URL的区别
- lambda表达式
- iOS点击状态栏回到顶部(一个控制器中包含多个scrollview,系统自带的回到顶部失效)
- Android 实现双击退出的功能
- Linux 网络管理、网络命令、远程登陆工具
- ETL简介
- 时间处理总结(三)javascript与WCF
- 让你的程序实现MaterialDesign风格
- CentOS6.6下源码安装apache2.4.20+PHP5.6.20
- hdu1720
- 企业数据可视化管理下的实践
- [LeetCode] 56. Merge Intervals
- Android系列之网络(二)----HTTP请求头与响应头
- 企业移动应用开发基本知识树 (Android & iOS)
- 二叉树的链式存储实现