HDOJ--3790--最短路径问题(双权值问题)

最短路径问题

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 18046    Accepted Submission(s): 5413

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

思路:这是一道双权值问题,两个权值的优先度不同,dis权值的优先度更高一些,cos略低,那么在做题的时候,考虑重边的时候需要考虑两个权值,更新的时候也需要考虑两个权值,剩下的就跟模板一样了。(小心在一些简单的地方,把代码给写错了)

ac代码:

#include<stdio.h>//双权值问题 ,注意权值的优先性。
#include<string.h>
#define INF 0x3f3f3f3f
#define N 1010
int n,m,dis[N],cos[N],map[N][N],cost[N][N],vis[N];
void init(){
	memset(map,INF,sizeof(map));
	memset(cost,INF,sizeof(cost));
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			if(i==j){
				cost[i][j]=0;
				map[i][j]=0;
			}
}
void getmap(){
	init();
	while(m--){
		int a,b,c,d;
		scanf("%d%d%d%d",&a,&b,&c,&d);
		if(map[a][b]>c||(map[a][b]==c&&cost[a][b]>d)){//考虑双权值的重边问题。
			map[a][b]=map[b][a]=c;
			cost[a][b]=cost[b][a]=d;//错写成cost[a][b]=cost[a][b],wa了1个多小时。心塞。
		}

	}
}
void dijkstra(){
	int s,t,i;
	scanf("%d%d",&s,&t);
	memset(vis,0,sizeof(vis));
	for(i=1;i<=n;i++){
		dis[i]=map[s][i];
		cos[i]=cost[s][i];
	}
	vis[s]=1;
	for(i=1;i<n;i++){
		int j,k,lowdis=INF,lowcost=INF;
		for(j=1;j<=n;j++)
			if(!vis[j]&&(lowdis>dis[j]||lowdis==dis[j]&&lowcost>cos[j])){
				lowdis=dis[k=j];
				lowcost=cos[k];
			}
		vis[k]=1;
		for(j=1;j<=n;j++)
			if(!vis[j]){//更新dis和cos时,考虑两个权值,先考虑权值优先度高的 。
				if(dis[j]>dis[k]+map[k][j]){
					dis[j]=dis[k]+map[k][j];
					cos[j]=cos[k]+cost[k][j];
				}
				if(dis[j]==dis[k]+map[k][j]){
					cos[j]=cos[k]+cost[k][j];
				}
			}
	}
	printf("%d %d\n",dis[t],cos[t]);
}
int main(){
	while(scanf("%d%d",&n,&m)!=EOF&&(n||m)){
		getmap();
		dijkstra();
	}
	return 0;
} 

版权声明:本文为小小呆原创文章,欲转载,请在后台勾搭本呆。

时间: 2024-10-12 20:54:29

HDOJ--3790--最短路径问题(双权值问题)的相关文章

hdu 3790 最短路径问题(双重权值,dijkstra算法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3790 题目大意:题意明了,输出最短路径及其花费. 需要注意的几点:(1)当最短路径相同时,输出最小花费!!! (2)更新路径的时候要注意更新花费. 1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 const int INF=9999999; 5 int map[1010][1010],Min,n,co

HDOJ 3790 最短路径问题 【双权值】

题意:... 难点:如何处理两个权值. 分析:题意说如果最短路径有多个,那么取价值最低的那个,所以说价值随着路径在变,如果路径不相等那么就更新路径并且更新价值,反之,则判断价值是不是要更新. 代码: #include<stdio.h> #include<string.h> #define M 1002 #define INF 0x3f3f3f3f int mapp[M][M], mapd[M][M], n, m, di[M], dp[M];//mapd是路径 mapp是价值 boo

HDOJ 3790 双权值Dijkstra

1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <cstring> 5 using namespace std; 6 7 const int INF = 1000000; 8 const int MAXSIZE = 1005; 9 10 int map[MAXSIZE][MAXSIZE]; 11 int price[MAXSIZE][MAXSIZE]; 1

hdoj(3790) 最短路径

最短路径问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 13577    Accepted Submission(s): 4156 Problem Description 给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的. Input

HDOJ 3790 最短路径问题(dijkstra算法)

最短路径问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 17968    Accepted Submission(s): 5385 Problem Description 给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的. Input

hdoj 3790 最短路径问题

最短路径问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 17986    Accepted Submission(s): 5394 Problem Description 给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费.假设最短距离有多条路线,则输出花费最少的. Input

AOJ2249 最短路+最小花费(双权值)

写题解之前先骂一下这道题 xxx给数据范围点数<1e4,边数<2e4,结果我开2e4和3e4都RE,然后找问题一个多小时,最后我开了1e5和2e5,题面太能唬人了吧!?真是sb题面 ------------------------------------------分割线------------------------------------ 题目大意:给n个点和m条边,每条边给了起始点,距离和价格,求在保证点1到其他n-1个点的路径都是最短路的前提下所有路的价格之和的最小值 简单的Dijks

POJ 2253 Frogger(Dijkstra变形——最短路径最小权值)

题目链接: http://poj.org/problem?id=2253 Description Freddy Frog is sitting on a stone in the middle of a lake. Suddenly he notices Fiona Frog who is sitting on another stone. He plans to visit her, but since the water is dirty and full of tourists' suns

有向图单源非负权值回路最短路径——BellmanFord算法

BellmanFord算法是一种暴力求解算法O(N3),它考虑所有情况,所以可以允许边的权值为负.(不过不允许出现负权值回路,因为那样会出现无限小) 之所以说它暴力,是因为它求出了每个节点所有长度为1的路径,再求所有长度为2的路径,并更新最短路径数组dist[]和path[],如此迭代直至求到长度n-1的路径.(n为图节点个数) 整体来看,每个节点纵向比较,从1到n-1长度的路径中取最小值作为最终路径长度. 因为它考虑了所有情况,所以负边也可以算出. 因为暴力,复杂度比Dijkstra高一个数量