Poj3635 Full Tank?

/* 从一个城市走到另一个城市,每个城市都有加油站,但是价格不同,油箱大小固定,计算行走过程中的最小花费。
1。使用优先队列,标记,链表表示边,二维数组超时
2。每次从优先队列中取的最小值,执行 油箱加一操作,if(v + 1 <= Capacity && !Sign[c][v + 1] && (Money[c][v+1]>m + Price[c]|| Money[c][v+1] == -1))更新Money和入队列。
3。更新到其他城市的花费~
*/
 
 
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
int Money[1001][101] ={0};
bool Sign[1001][101];
int Price[1001];


int City,Road,Query;
int Capacity,First,Last;
void dij(int Capacity,int First,int Last);
struct EdgeStruct
{
	EdgeStruct(int c,int distance,EdgeStruct* next = NULL)
	{
		City = c;
		Distance = distance;
		Next = next;
	};
	int City;
	int Distance;
	EdgeStruct * Next;
};
EdgeStruct* CityEdge[1001];

class Pair 
{
public:
	Pair(int c,int v,int m)
	{City =c;CurrentVehicle = v;Money = m;}
	friend bool operator< (const Pair& n1, const Pair& n2)
	{
		return n1.Money > n2.Money;
	}
	int City;
	int CurrentVehicle;
	int Money;
};



int main()
{
	cin>>City>>Road; 
	for(int i = 0;i < City; i++)
	{
		cin>>Price[i];
	}
	int distance;
	memset(CityEdge,NULL,sizeof(CityEdge));
	
	for(int i = 0; i < Road; i++)
	{
		cin>>First>>Last;
		cin>>distance;
		CityEdge[First] = new EdgeStruct(Last,distance,CityEdge[First]);
		CityEdge[Last] = new EdgeStruct(First,distance,CityEdge[Last]);
	}
	cin>>Query;
	for(int i = 0; i < Query ; i++)
	{
		cin>>Capacity>>First>>Last;
		dij(Capacity,First,Last);
	}
	return 1;
}
void dij(int Capacity,int First,int Last)
{
	priority_queue<Pair> Queue;
	memset(Money,0xff,sizeof(Money));
	memset(Sign,0,sizeof(Sign));

	Money[First][0] = 0;
		

	Queue.push(Pair(First,0,Money[First][0]));

	int c;
	int v;
	int m;
	while(!Queue.empty())
	{
		c = Queue.top().City;
		v = Queue.top().CurrentVehicle;
		m = Queue.top().Money;
		Queue.pop();
		if(Sign[c][v])continue;
		Sign[c][v] = true;		
		if(c == Last)
		{
			if(Money[c][v] != -1)
				cout<<Money[c][v]<<endl;
			else cout<<"impossible"<<endl;
			return ;
		}
		
		if(v + 1 <= Capacity && !Sign[c][v + 1] && (Money[c][v+1]>m + Price[c]|| Money[c][v+1] == -1))
		{
			Money[c][v+1] = m + Price[c];
			Queue.push(Pair(c,v + 1,Money[c][v+1]));
		}
		EdgeStruct* edge = CityEdge[c];
		while(edge)
		{
			if(v >= edge->Distance && !Sign[edge->City][v -edge->Distance] && (Money[edge->City][v -edge->Distance] > m || Money[edge->City][v -edge->Distance] == -1))
			{
				Money[edge->City][v -edge->Distance] = m;
				Queue.push(Pair(edge->City,v -edge->Distance,Money[edge->City][v -edge->Distance]));
			}
			edge = edge->Next;
		}

	}
	if(Queue.empty())cout<<"impossible"<<endl;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值