1030 Travel Plan (30 分)

Keywords: dij weight on edge

A traveler’s map gives the distances between cities along the highways, together with the cost of each highway. Now you are supposed to write a program to help a traveler to decide the shortest path between his/her starting city and the destination. If such a shortest path is not unique, you are supposed to output the one with the minimum cost, which is guaranteed to be unique.

Input Specification:

where the numbers are all integers no more than 500, and are separated by a space.
在这里插入图片描述

Output Specification:

For each test case, print in one line the cities along the shortest path from the starting point to the destination, followed by the total distance and the total cost of the path. The numbers must be separated by a space and there must be no extra space at the end of output.

Sample Input:

4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20

Sample Output:

0 2 3 3 40

Note:

  1. 题意在这里插入图片描述
  2. 注意费时一小时,题目很简单但是第一遍读题不仔细,以为输出的是dij经过的节点个数,其实是路径长度(两者恰巧相等)
  3. debug时看到网上他人代码有输入边查重,可以考虑,以防变态数据

Code1

#include<iostream>
#include<fstream>
#include<vector>
using namespace std;
const int MAX = 1e4 ;
int sum_cost[MAX], cost[MAX][MAX], path[MAX];
int collected[MAX] = {0},a[MAX][MAX], distances[MAX], num;
void Dijkstra(int start){
	collected[start] = 1;
	while(1){
		int min = MAX, ptr;
		for(int i = 0;i < num; i++){
			if(collected[i] == 0 && distances[i] < min){
				min = distances[i];
				ptr = i;
			}
		}
		if(min == MAX) break;
		collected[ptr] = 1;
		for(int i = 0; i < num; i++){
			if(collected[i] == 0 && a[ptr][i] + distances[ptr] < distances[i]){
				sum_cost[i] = sum_cost[ptr] + cost[ptr][i];
				distances[i] = a[ptr][i] + distances[ptr];
				path[i] = ptr;
			}
			else if(collected[i] == 0 && a[ptr][i] + distances[ptr] == distances[i]){
				if(sum_cost[ptr] + cost[ptr][i] < sum_cost[i]){
					sum_cost[i] = sum_cost[ptr] + cost[ptr][i];
					path[i] = ptr;
				}
			}
		}
	}
}
int main(){
	int start, des, edge;
#ifdef _DEBUG
	ifstream cin("data.txt");
#endif

	cin >> num >> edge >> start >> des;
	fill(a[0], a[0] +  MAX * ( num), MAX);
	fill(distances, distances + num, MAX);
    fill(cost[0], cost[0] +  MAX * (num), MAX);
 
 
	for(int i  = 0; i < edge; i++){
		int tempa, tempb, tempc, tempd;
		cin >> tempa >> tempb >> tempc >> tempd;
	
        if(a[tempa][tempb] > tempc) { //当有重边时,更新相关信息			
        	a[tempa][tempb] = tempc;
		    a[tempb][tempa] = tempc;
		    cost[tempa][tempb] = tempd;
            cost[tempb][tempa] = tempd;		
        }			
        if(a[tempa][tempb] == tempc && tempd<cost[tempa][tempb]) {
            a[tempa][tempb] = tempc;
		    a[tempb][tempa] = tempc;
		    cost[tempa][tempb] = tempd;
            cost[tempb][tempa] = tempd;	
        }

	}
	for(int i = 0; i < num; i++){
		if(a[start][i] < MAX){
			distances[i] = a[start][i];
			path[i] = start;
			sum_cost[i] = cost[start][i];
		}
		
	}
	path[start] = -1;
	Dijkstra(start	);
	int temp =path[des], cnt = 0, real_path[MAX],  min_dis = a[des][temp];
	while(temp != -1){
        if(path[temp] > -1)
        min_dis += a[temp][path[temp]];
		real_path[cnt++] = temp;
		temp = path[temp];
        
	}
	for(int i = cnt - 1; i >= 0; i--){
		cout << real_path[i] << " ";
	}
	cout << des << " " <<  min_dis << " " << sum_cost[des];
#ifdef _DUBUG
	cin.close();
#endif
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值