PAT A1030 Travel Plan(30)

题意

  • 还是dijkstra最短路径题,路的边权分两个,distcost,第一标尺是dist最小,第二标尺是cost最小,此时唯一。

注意

  1. 这道题还要输出路径,所以为每个点记录前驱,最后来一个递归输出。

代码

#include <iostream>
#include <algorithm>
#include <climits>
using namespace std;

const int Nmax = 500;
int N, M, S, D;
int dist[Nmax][Nmax];
int cost[Nmax][Nmax];

int m_dist[Nmax];
int m_cost[Nmax];
bool s[Nmax];
int v[Nmax];

void DIJKSTRA(int s0)
{
	fill(m_dist, m_dist + Nmax, INT_MAX);
	fill(s, s + Nmax, false);
	m_dist[s0] = 0;
	m_cost[s0] = 0;
	for (int i = 0; i < N; i++)
	{
		int min = INT_MAX, k;
		for (int j = 0; j < N; j++)
		{
			if (!s[j] && m_dist[j] < min)
			{
				min = m_dist[j];
				k = j;
			}
		}
		s[k] = true;
		for (int j = 0; j < N; j++)
		{
			if (!s[j] && dist[k][j] != INT_MAX)
			{
				if (m_dist[k] + dist[k][j] < m_dist[j])
				{
					m_dist[j] = m_dist[k] + dist[k][j];
					m_cost[j] = m_cost[k] + cost[k][j];
					v[j] = k;
				}
				else if (m_dist[k] + dist[k][j] == m_dist[j] && m_cost[k] + cost[k][j] < m_cost[j])
				{
					m_cost[j] = m_cost[k] + cost[k][j];
					v[j] = k;
				}
			}
		}
	}
}

void PRINT(int d)
{
	if (d == S)
	{
		cout << d;
		return;
	}
	PRINT(v[d]);
	cout << " " << d;
}

int main()
{
	cin >> N >> M >> S >> D;
	int c1, c2;
	fill(dist[0], dist[0] + Nmax*Nmax, INT_MAX);
	for (int i = 0; i < M; i++)
	{
		cin >> c1 >> c2;
		cin >> dist[c1][c2];
		cin >> cost[c1][c2];
		dist[c2][c1] = dist[c1][c2];
		cost[c2][c1] = cost[c1][c2];
	}
	DIJKSTRA(S);
	PRINT(D);
	cout << " " << m_dist[D] << " " << m_cost[D];

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值