POJ 1062.昂贵的聘礼

题目:http://poj.org/problem?id=1062

AC代码(C++):

#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <vector>
#include <queue>
#include <math.h>
#include <string>
#include <string.h>
#include <bitset>

#define INF 0xfffffff

using namespace std;

struct ITEM{
	int p;
	int l;
};

int m, n;
ITEM* item;
int map[105][105];
int Min;
bool vis[105];
int HL,LL;

void dfs(int num, int dist){
	vis[num] = true;
	int tmpHL = HL;
	int tmpLL = LL;
	if(item[num].l+m<HL)HL=item[num].l+m;
	if(item[num].l-m>LL)LL=item[num].l-m;
	for(int i = 1; i <= n; i++){
		if(map[num][i]==-1||vis[i]==true||item[i].l>HL||item[i].l<LL)continue;
		int tmp = item[i].p + dist + map[num][i];
		if(tmp<Min)Min = tmp;
		dfs(i, dist+map[num][i]);
	}
	HL = tmpHL;
	LL = tmpLL;
	vis[num] = false;
}

int main(){
	memset(map,INF,sizeof(map));
	memset(vis,false,sizeof(vis));
	cin>>m>>n;
	item = new ITEM[n+1];
	for(int i = 1; i <= n; i++){
		int x;
		cin>>item[i].p>>item[i].l>>x;
		for(int j = 0; j < x; j++){
			int t,v;
			cin>>t>>v;
			map[i][t] = v;
		}
	}
	Min = item[1].p;
	HL = item[1].l + m;
	LL = item[1].l - m;
	dfs(1,0);
	cout<<Min;
}
总结:

1.题目的意思看似很复杂其实很简单, 从物品1开始, 有替代品就生成一条边, 边的权值就是优惠价, 边的另一头就是替代的物品, 再以这个替代物品继续往下生成, 知道没有替代品. 于是得到了一个图, 我们只需要从物品1开始遍历每个节点(用什么方法都行), 在到达每个节点的时候计算到这一节点时的总费用(即经过的所有边+这个节点物品本身的价值), 然后与全局最小值Min比较赋值, 遍历一遍后得到的Min就是答案.

2.这题有几个坑点, 一个是每个物品的等级L, 网上有些人的代码直接拿L跟物品1的L比较, 这是不对的(至少我提交不行, 不知道他们是怎么弄成可以的). 我的处理办法是取一个区间, 深搜到达一个节点时更新一次区间范围, 离开节点时还原, 具体操作见代码.

3.还有一个坑点是, 不要开数组来保存边信息, 测试里会有很多物品+每个物品有大量替代, 导致MLE. 解决办法是用二维数组map来保存边信息.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值