B - 最短路径问题 HDU-3790(Dijkstra算法的简单应用)

B - 最短路径问题

给你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
题意:给你一个无向图,路的信息有关距离和花费,再给定起点和终点,求起点到终点的最小距离和花费,若最小距离有多个,选择花费最小的那个。


解题思路:这是一个单源点最短路径问题,我们明显是要用Dijkstra算法去解决,这里还多了一个信息就是花费,这没有多大影响,因为我们的核心是最短路径,其次再考虑花费,还有这里要注意的一点就是两点之间可能不只是只有一条路,我们还需要进行判断。同样,由于输入数据量过多,我们要使用scanf输入,用输入流cin会超时。


AC代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<stack>
#include<queue>
#include<cstring>
#include<map>
#include<iterator>
#include<list>
#include<set>
#include<functional>
#include<memory.h>

using namespace std;

int n,m;
const int maxn=1005;
const int inf=0x3f3f3f3f;//表示无穷大。
int graph[maxn][maxn];
int dis[maxn];//起点到终点的最短距离。
int spend[maxn][maxn];//cost[i][j]表示从i到达j的花费。
int cost[maxn];//cost[i]表示起点到i的花费。
int visited[maxn];//判断是否已经访问过。
int S,E;//起点和终点。
void init(){
	memset(dis,inf,sizeof(dis));
	memset(graph,inf,sizeof(graph));
	memset(visited,false,sizeof(visited));
	memset(cost,inf,sizeof(cost));

}
void Dijkstra(int S){
	dis[S]=0;
	cost[S]=0;
	int minn,pos;
	while(1){
		minn=inf;pos=-1;
		for(int i=1;i<=n;i++){
			if(!visited[i]&&dis[i]<minn){
				minn=dis[i];
				pos=i;
			}
		}
		if(pos==-1)break;
		visited[pos]=true;
		for(int i=1;i<=n;i++){
			if(!visited[i]&&dis[i]>dis[pos]+graph[pos][i]){
				dis[i]=dis[pos]+graph[pos][i];
				cost[i]=cost[pos]+spend[pos][i];
			}
			else if(!visited[i]&&dis[i]==dis[pos]+graph[pos][i]){
				if(cost[i]>cost[pos]+spend[pos][i])
					cost[i]=cost[pos]+spend[pos][i];
			}
		}
	}
}
int main(){
	while(cin>>n>>m&&(n+m)){
		int a,b,d,p;
		init();
		for(int i=0;i<m;i++){
			scanf("%d%d%d%d",&a,&b,&d,&p);
			if(d<graph[a][b]){
			graph[a][b]=graph[b][a]=d;
			spend[a][b]=spend[b][a]=p;
			}
			else if(d==graph[a][b]&&p<spend[a][b]){
				spend[a][b]=spend[b][a]=p;
			}
		}
		scanf("%d%d",&S,&E);
		Dijkstra(S);
		printf("%d %d\n",dis[E],cost[E]);
	}
	return 0;
}
posted @   unique_pursuit  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
点击右上角即可分享
微信分享提示