poj1062昂贵的聘礼有等级限制的最短路径

61 篇文章 0 订阅
10 篇文章 0 订阅

//主要问题是在最短路径过程中注意等级的差距

//第一次用的以当前起点为最大等级或者最小等级

//后来发现效率较低,考虑用minlevel和maxlevel存储

//那么要到达酋长点,其他等级必须在minlevel<=level<=maxlevel之间的才进行更新

//0ms 196K

#include <iostream>
#include <algorithm>
#include <utility>
#include <vector>
#include <queue>
using namespace std;
#define MAX_V  110
#define  INF 0x3f3f3f3f
static int M,N;//M表示的是等级差两个物品等级差大于M那么就不能到达
static int P,L,X;

static struct good
{
	int p;
	int l;
	int x;
}Goods[300];

static struct edge
{
	edge(int _t,int _c):to(_t),cost(_c)
	{

	}
	int to,cost;
};
typedef pair<int,int>p;
static int V;
vector<edge>G[MAX_V];
static int d[MAX_V];
static int minlevel;
static int maxlevel;
static void addedge(int from,int to,int v)
{
	G[from].push_back(edge(to,v));
}

static int dijkstra(int s)
{
	int res = INF;
	priority_queue<p,vector<p>,greater<p> >que;//从小到大
	fill(d,d+V+1,INF);
	d[s] = 0;
	int level = Goods[s].l;
	que.push(p(0,s));
	res = Goods[s].p;
	while(!que.empty())
	{
		p p0 = que.top();que.pop();
		int v = p0.second;
		if (d[v]<p0.first)
		 continue;
		for (int i=0;i<G[v].size();++i)
		{
			edge e = G[v][i];
			if (d[e.to]>d[v]+e.cost)
			{
				if (Goods[e.to].l<minlevel)//为最小等级的时候
					continue;
				if (Goods[e.to].l>maxlevel)//为最大等级的时候
				    continue;
				d[e.to] = d[v] + e.cost;
				que.push(p(d[e.to],e.to));
			}
			if (d[e.to]+Goods[e.to].p<res)
			{
				res = d[e.to] + Goods[e.to].p;
			}
		}
	}
	return res;
}
static void solve()
{
	int ans = INF;
	int qiuLevel = Goods[1].l;
	//要到达酋长那么就应该在这个范围之内所有等级
	for (int i = qiuLevel-M;i<=qiuLevel;++i ){
		minlevel = i;
		maxlevel = i+M;
		int ret = dijkstra(1);
		if(ans> ret)
			ans = ret;
	}
	printf("%d\n",ans);
}

int main()
{
	scanf("%d %d",&M,&N);
	V= N;
	for (int i=1;i<=N;++i)
	{
		scanf("%d %d %d",&Goods[i].p,&Goods[i].l,&Goods[i].x);
		int t,val;
		for (int j=0;j<Goods[i].x;++j)
		{
			scanf("%d %d",&t,&val);
			addedge(i,t,val);
		}                              
	}
	solve();      
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值