hdu3790(最短路径问题)

来源:互联网 发布:2017网络事件 编辑:程序博客网 时间:2024/06/05 11:41
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
 
#include <iostream>#include <cstdio>#include <cstring>#include <vector>#include <cmath>#include <queue>#define N 1005#define inf 1000000using namespace std;int w[N][N],v[N][N],vis[N],dis[N],fee[N];void init(int n)//初始化 {for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){w[i][j]=inf;v[i][j]=inf;}}memset(vis,0,sizeof(vis));memset(dis,0,sizeof(dis));memset(fee,0,sizeof(fee));}void Dijstra(int s,int e,int n){for(int i=1;i<=n;i++)//跟起点的距离、费用 {dis[i]=w[s][i];fee[i]=v[s][i];}dis[s]=0;//自己到自己的距离、费用为0 fee[s]=0;vis[s]=1;//标记为访问 for(int i=1;i<=n;i++){int pos,Min=inf;for(int j=1;j<=n;j++)//寻找与当前点距离最短的点 {if(!vis[j]&&dis[j]<Min){Min=dis[j];pos=j;}}if(Min==inf)//如果为inf,则说明无法到达 break;vis[pos]=1;//标记访问 for(int j=1;j<=n;j++)//松弛操作 {if(!vis[j])//如果没有访问 {if(dis[j]>dis[pos]+w[pos][j])//如果从j到pos点再到当前点的距离小于j到当前点的距离 {dis[j]=dis[pos]+w[pos][j];fee[j]=fee[pos]+v[pos][j];}else if(dis[j]==dis[pos]+w[pos][j]&&fee[j]>fee[pos]+v[pos][j])//如果距离相同,就找费用小的 {fee[j]=fee[pos]+v[pos][j];}}}}printf("%d %d\n",dis[e],fee[e]);}int main(){int n,m,a,b,p,q,s,e;while(~scanf("%d%d",&n,&m)&&(n+m)){init(n);for(int i=0;i<m;i++){scanf("%d%d%d%d",&a,&b,&p,&q);if(w[a][b]>p||(w[a][b]==p&&v[a][b]>q))//添加距离更短或者当距离相等时,费用更少的边 {w[a][b]=w[b][a]=p;v[a][b]=v[b][a]=q;}}scanf("%d%d",&s,&e);//输入起点、终点 Dijstra(s,e,n);}}

0 0
原创粉丝点击