hdu 3790 最短路径问题 dijkstra模板 双重权值

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3790 

题目大意:题意明了,输出最短路径及其花费。

需要注意的几点:

  • 当最短路径相同时,输出最小花费!!!
  • 更新路径的时候要注意更新花费。
  • 涉及重边的问题还得把相同路径长度但花费最小的边同时更新才对,虽然没改也AC,不过是数据问题

AC代码,先写了一模一样的java代码改的,java超时噢耶

#include <iostream>
#include <cstdio>
using namespace std;

int n,m,a,b,d,p,x,y;
int map[1005][1005];
int w[1005][1005];
bool vis[1005];
int dis[1005];
int cost[1005];
int INF = 999999999;//9个9,求平安
	
void dijkstra() {
	for(int i=1;i<=n;i++) {
		dis[i] = map[x][i];
		cost[i] = w[x][i];
	}
	dis[x] = 0;
	cost[x] = 0;
	vis[x] = true;
	
	for(int i=1;i<n;i++) {//遍历n-1个顶点
		int k = -1;
		
	for(int j=1;j<=n;j++)
		if(!vis[j] && (k==-1 || dis[j] < dis[k] || (dis[j]==dis[k] && cost[j]<cost[k])))
			k = j;
		if(k==-1)
			break;
		vis[k] = true;
		for(int j=1;j<=n;j++)
			if(!vis[j] && (dis[j]>dis[k]+map[k][j] || (dis[j]==dis[k]+map[k][j] && cost[j]>cost[k]+w[k][j]))) {
				dis[j] = dis[k]+map[k][j];
				cost[j] = cost[k]+w[k][j];
			}
	}
	
	printf("%d %d\n",dis[y],cost[y]);
}


int main() {
	while(~scanf("%d%d",&n,&m)) {
		if(n==0)
			break;

		memset(vis,false,sizeof(vis));
		memset(dis,0,sizeof(dis));
		memset(cost,0,sizeof(cost));

		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				if(i!=j) {
					map[i][j] = INF;
					w[i][j] = INF;
				} else{
					map[i][j] = 0;
					w[i][j] = 0;					
				}

		for(int i=1;i<=m;i++) {
			scanf("%d%d%d%d",&a,&b,&d,&p);
			if(d<map[a][b] || (d==map[a][b] && p<w[a][b])) {
				map[a][b] = map[b][a] = d;
				w[a][b] = w[b][a] = p;
			}
		}
		scanf("%d%d",&x,&y);
		
		dijkstra();
	}	
}

也发发上面改来的java代码吧

import java.util.Scanner;

public class hdu3790 {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		
		while(in.hasNext()) {
			n = in.nextInt();
			m = in.nextInt();
			if(n==0)
				break;
			map = new int[n+5][n+5];
			w = new int[n+5][n+5];
			vis = new boolean[n+5];
			dis = new int[n+5];
			cost = new int[n+5];
			
			for(int i=1;i<=n;i++)
				for(int j=1;j<=n;j++)
					if(i!=j) {
						map[i][j] = INF;
						w[i][j] = INF;
					}
			
			for(int i=1;i<=m;i++) {
				a = in.nextInt();
				b = in.nextInt();
				d = in.nextInt();
				p = in.nextInt();
				if(d<map[a][b] || (d==map[a][b] && p<w[a][b])) {
					map[a][b] = map[b][a] = d;
					w[a][b] = w[b][a] = p;
				}
			}
			x = in.nextInt();
			y = in.nextInt();
			
			dijkstra();
		}
		
	}
	
	static int n,m,a,b,d,p,x,y;
	static int[][] map;
	static int[][] w;
	static boolean[] vis;
	static int[] dis;
	static int[] cost;

	static int INF = 999999999;//9个9,求平安
	
	static void dijkstra() {
		for(int i=1;i<=n;i++) {
			dis[i] = map[x][i];
			cost[i] = w[x][i];
		}
		dis[x] = 0;
		cost[x] = 0;
		vis[x] = true;
		
		for(int i=1;i<n;i++) {//遍历n-1个顶点
			int k = -1;
			
			for(int j=1;j<=n;j++)
				if(!vis[j] && (k==-1 || dis[j] < dis[k] || (dis[j]==dis[k] && cost[j]<cost[k])))
					k = j;
			if(k==-1)
				break;
			vis[k] = true;
			for(int j=1;j<=n;j++)
				if(!vis[j] && (dis[j]>dis[k]+map[k][j] || (dis[j]==dis[k]+map[k][j] && cost[j]>cost[k]+w[k][j]))) {
					dis[j] = dis[k]+map[k][j];
					cost[j] = cost[k]+w[k][j];
				}
		}
		
		System.out.println(dis[y]+" "+cost[y]);
	}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值