POJ1062 - 昂贵的聘礼

非负权的单源最短路径,果断用dijkstra算法

需要注意的是这里是有交易的双方是有等级限制的,假设族长等级为Level0,最大可交易等级差为M,解决方案是,依次假设旅行者的等级为 Level0-M、Level0-M+1、Level0-M+2.......Level0+M,然后让旅行者只和等级不低于他的人交易,然后比较这2M+1次的结果,取最小值。


//Memory Time
//292K	16MS

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

struct edge
{
	edge* next;
	int dst;
	int cost;
};
edge* eg[101];

struct vertex
{
	int src;
	int level;
	int cost;
};
vertex vex[101];

bool cmp(vertex &a, vertex &b)
{
	return a.cost > b.cost;
}

int main()
{
	int M, N;
	cin >> M >> N;
	
	for(int i = 0; i <= N; i++)
		eg[i] = NULL;
	
	for(int i = 0; i < N; i++)
	{
		int price, level, num;
		cin>>price>>level>>num;
		vex[i].src = i;
		vex[i].level = level;
		vex[i].cost = 2000000000;
		
		edge* e = new edge;
		e->next = eg[N];
		e->dst  = i;
		e->cost = price;
		eg[N] = e;
		
		for(int j = 0; j < num; j++)
		{
			int src, price;
			cin >> src >> price;
			src--;
			edge* e = new edge;
			e->next = eg[src];
			e->dst  = i;
			e->cost = price;
			eg[src] = e;
		}
	}
	
	int minCost = 2000000000;
	for(int t = M; t >= 0; t--)
	{
		for(int i = 0; i< N; i++)
			vex[i].cost = 2000000000;
		
		vector<vertex> v;
		vex[N].level = vex[0].level - t;
		vex[N].src = N;
		vex[N].cost = 0;
		edge* e = eg[N];
		while(e != NULL)
		{
			int dst = e->dst;
			int tempCost = e->cost + vex[N].cost;
			bool tempBool = (vex[dst].level - vex[N].level >= 0 && vex[dst].level - vex[N].level <= M);
			if(tempCost < vex[dst].cost && tempBool)
			{
				vex[dst].cost = tempCost;
				v.push_back(vex[dst]);
				push_heap(v.begin(), v.end(), cmp);
			}
			e = e->next;
		}
	
		while(v.size() > 0)
		{
			vertex tempV = v.front();
			pop_heap(v.begin(),v.end(), cmp);
			v.pop_back();
		
			if(tempV.src == 0)
			{
				break;
			}
		
			int src = tempV.src;
			edge* e = eg[src];
			while(e != NULL)
			{
				int dst = e->dst;
				int tempCost = e->cost + vex[src].cost;
				bool tempBool = (vex[dst].level - vex[N].level >= 0 && vex[dst].level - vex[N].level <= M);
				if(tempCost < vex[dst].cost && tempBool)
				{
					vex[dst].cost = tempCost;
					v.push_back(vex[dst]);
					push_heap(v.begin(), v.end(), cmp);
				}
				e = e->next;
			}
		}
		if(minCost > vex[0].cost)
			minCost = vex[0].cost;
	}
	
	cout << minCost;
	
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值