Travel Plan

http://pat.zju.edu.cn/contests/pat-a-practise/1030

单源最短路径,多个权值的情况。

#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#include <stack>
using namespace std;

#define INF 0x0FFFFFFF

struct Node{
	int dis, cost;
};

Node tmap[505][505];
int n, m, s, d;

struct Ans{
	int dist, cost;
	vector<int>path;
};

void diji(int s, int d)
{
	Ans result[505];
	int i;
	bool isVisted[505];
	memset(isVisted, 0, sizeof(isVisted));
	for(i = 0; i < n; i ++)
	{
		result[i].dist = tmap[s][i].dis;
		result[i].cost = tmap[s][i].cost;
		result[i].path.clear();
		if(result[i].dist < INF && i != s) result[i].path.push_back(i);
	}
	result[s].dist = 0;
	result[s].path.push_back(s);
	isVisted[s] = true;
	int CASE = n;
	while(--CASE)
	{
		int min_dist = INF, min_cost = INF, index;
		for(i = 0; i < n; i ++)
		{
			if(!isVisted[i] && (result[i].dist < min_dist || 
				(result[i].dist == min_dist && result[i].cost < min_cost)))
			{
				min_dist = result[i].dist;
				min_cost = result[i].cost;
				index = i;
			}
		}

		isVisted[index] = true;
		if(index == d)
		{
			
			cout<<s;
			for(int x = 0; x < result[index].path.size(); x ++) cout<<' '<<result[index].path[x];
			cout<<' '<<min_dist<<' '<<min_cost<<endl;
			return;
		}

		for(i = 0; i < n; i ++)
		{
			if(!isVisted[i])
			{
				if( (min_dist + tmap[index][i].dis < result[i].dist) ||
					( (min_dist + tmap[index][i].dis == result[i].dist) && 
					min_cost + tmap[index][i].cost < result[i].cost) )
				{
					result[i].dist = min_dist + tmap[index][i].dis;
					result[i].cost = min_cost + tmap[index][i].cost;
					result[i].path.clear();
					for(int k = 0; k < result[index].path.size(); k ++)
						result[i].path.push_back(result[index].path[k]);
					result[i].path.push_back(i);
				}
			}
		}
	}

}

int main()
{
	int i, j, a, b, x;
	
	scanf("%d %d %d %d", &n, &m, &s, &d);

	for(i = 0; i < n; i ++)
		for(j = 0; j < n; j ++)
		{
			if(i != j)
			{
				tmap[i][j].dis = tmap[j][i].dis = INF;
				tmap[i][j].cost = tmap[j][i].cost = INF;
			}
		}

	for(i = 0; i < m; i ++)
	{
		scanf("%d %d %d %d", &a, &b, &j, &x);
		tmap[a][b].cost = tmap[b][a].cost = x;
		tmap[a][b].dis = tmap[b][a].dis = j;
	}
	diji(s, d);
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值