POJ 1062 广搜+剪枝

昂贵的聘礼

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 37139   Accepted: 10721

Description

年轻的探险家来到了一个印第安部落里。在那里他和酋长的女儿相爱了,于是便向酋长去求亲。酋长要他用10000个金币作为聘礼才答应把女儿嫁给他。探险家拿不出这么多金币,便请求酋长降低要求。酋长说:"嗯,如果你能够替我弄到大祭司的皮袄,我可以只要8000金币。如果你能够弄来他的水晶球,那么只要5000金币就行了。"探险家就跑到大祭司那里,向他要求皮袄或水晶球,大祭司要他用金币来换,或者替他弄来其他的东西,他可以降低价格。探险家于是又跑到其他地方,其他人也提出了类似的要求,或者直接用金币换,或者找到其他东西就可以降低价格。不过探险家没必要用多样东西去换一样东西,因为不会得到更低的价格。探险家现在很需要你的帮忙,让他用最少的金币娶到自己的心上人。另外他要告诉你的是,在这个部落里,等级观念十分森严。地位差距超过一定限制的两个人之间不会进行任何形式的直接接触,包括交易。他是一个外来人,所以可以不受这些限制。但是如果他和某个地位较低的人进行了交易,地位较高的的人不会再和他交易,他们认为这样等于是间接接触,反过来也一样。因此你需要在考虑所有的情况以后给他提供一个最好的方案。 
为了方便起见,我们把所有的物品从1开始进行编号,酋长的允诺也看作一个物品,并且编号总是1。每个物品都有对应的价格P,主人的地位等级L,以及一系列的替代品Ti和该替代品所对应的"优惠"Vi。如果两人地位等级差距超过了M,就不能"间接交易"。你必须根据这些数据来计算出探险家最少需要多少金币才能娶到酋长的女儿。

Input

输入第一行是两个整数M,N(1 <= N <= 100),依次表示地位等级差距限制和物品的总数。接下来按照编号从小到大依次给出了N个物品的描述。每个物品的描述开头是三个非负整数P、L、X(X < N),依次表示该物品的价格、主人的地位等级和替代品总数。接下来X行每行包括两个整数T和V,分别表示替代品的编号和"优惠价格"。

Output

输出最少需要的金币数。

Sample Input

1 4
10000 3 2
2 8000
3 5000
1000 2 1
4 200
3000 2 1
4 200
50 2 0

Sample Output

5250

初看这道题时我很激动,终于看见一道中文题了。。。略加思考,必定是广搜。。然后就激动万分的敲代码,敲完后提交。。提交了一遍又一遍总是wa。。然后在dicuss中找样例,全部过了还是wa,于是看代码,发现广搜时if中多了一个条件,我的代码就带有贪心的意思了,而贪心解未必就是最优解,提交就过了。。。

代码:
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <queue>
 6 #include <vector>
 7
 8 using namespace std;
 9 #define N 2205
10 #define inf 999999999
11
12 struct node{
13     int y, p, mx, mn, z;
14 };
15
16 vector<node>ve[N];
17 int price[N], l[N], visited[N];
18 int n, m;
19
20 void init(){
21     int i;
22     for(i=0;i<=n;i++){
23         ve[i].clear();
24     }
25     memset(visited,0,sizeof(visited));
26     memset(price,0,sizeof(price));
27     memset(l,0,sizeof(l));
28 }
29
30 int bfs(){
31     int i, j, k, u, v, ans;
32     node p, q;
33     queue<node>Q;
34     p.y=1;p.p=0;p.mx=p.mn=l[1];p.z=price[p.y];
35     ans=p.z;
36     visited[p.y]=1;
37     Q.push(p);
38     while(!Q.empty()){
39         p=Q.front();
40         Q.pop();
41
42         visited[p.y]=0;
43         for(i=0;i<ve[p.y].size();i++){
44             q=ve[p.y][i];
45             if((abs(l[q.y]-p.mx)<=m&&abs(l[q.y]-p.mn)<=m)&&(p.p+q.p)<=ans){//(p.q+q.p)<=ans去掉就会超时
46                 q.z=price[q.y]+q.p+p.p;
47                 ans=min(ans,q.z);
48                     q.p=q.p+p.p;
49                     q.mx=max(p.mx,l[q.y]);
50                     q.mn=min(p.mn,l[q.y]);
51                 //    printf("       %d %d %d %d\n",p.y,q.y,q.mx,q.mn);
52                     Q.push(q);
53
54             }
55         }
56     }
57
58
59     //cout<<endl;
60     return ans;
61 }
62
63
64 main()
65 {
66     int i, j, k, x, y, z;
67     while(scanf("%d %d",&m,&n)==2){
68         init();
69         node p;
70         for(i=1;i<=n;i++){
71             scanf("%d %d %d",&price[i],&l[i],&z);
72             while(z--){
73                 scanf("%d %d",&x,&y);
74                 p.y=x;p.p=y;
75                 ve[i].push_back(p);
76             }
77         }
78         printf("%d\n",bfs());
79     }
80 }
时间: 2024-10-14 19:28:19

POJ 1062 广搜+剪枝的相关文章

HDU 1026 Ignatius and the Princess I 迷宫广搜剪枝问题

本题是个经典的迷宫广搜问题类型了.网上看到好多解法. 很多解题报告都没什么分析,更不会指出其中的关键点.代码更加像一大抄.有人分析也一大篇分析,不过全部都不切中关键,甚至在分析什么广搜和深搜区别,广搜为什么快之类的,还有喊什么暴搜之类的,全错了.估计这些代码都是抄过的. 通过一大段的时间研究,终于搞通了. 本题虽然可以说是广搜,但是其中的关键却是剪枝法,为什么呢? 因为迷宫并不能简单地广搜就能搜索出所有路径的,甚至只要迷宫大点就不能搜索出是否有路径,如果没有条件剪枝的情况下:不信,你严格写一个广

POJ 3322(广搜)

---恢复内容开始--- http://poj.org/problem?id=3322 题意:http://jandan.net/2008/01/24/bloxorz.html就是这个鬼游戏 我也是郁闷了,昨天就看到一道连连看的题目,今天就是这个游戏.都懵逼了. 思路:这个游戏的难度主要是在于它是第一个长方体,而不是一个正方体,不过是正方体也就不存在这个游戏了,所以我们要想办法来标记它. 我首先定义了这个长方体有三种状态. 对于第一种状态来说,它是的底面是一个正方形,四边都是一个长方形. 第二种

Poj3414广搜

<span style="color:#330099;">/* D - D Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit Status Practice POJ 3414 Description You are given two pots, having the volume of A and B liters respectively. The follow

poj 1166 The Clocks 记录路径的广搜

题意: 给9个时钟的初始状态,和一些对某几个钟的操作,求最少经过几步能到目标状态(全指向12点). 分析: 明显的广搜,但实现起来的细节要注意:1.因为要记录路径,所以要在整个程序执行过程中扩展出的节点在输出路径前不能销毁, 故采用静态内存分配的方法(开node[600000],用get_node()创建节点.2.queue<node>比queue<int>要多花1别的时间. //poj 1166 //sep9 #include <iostream> #include

双向广搜 POJ 3126 Prime Path

POJ 3126  Prime Path Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16204   Accepted: 9153 Description The ministers of the cabinet were quite upset by the message from the Chief of Security stating that they would all have to change th

广搜+打表 POJ 1426 Find The Multiple

POJ 1426   Find The Multiple Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 25734   Accepted: 10613   Special Judge Description Given a positive integer n, write a program to find out a nonzero multiple m of n whose decimal representati

poj 3126 prime path 简单广搜

http://poj.org/problem?id=3126 题意:给你两个四位数a,b,从a开始    每次只能改变上一次数的其中一位,问至少需要几步才能得到b 分析:求最小路   典型的广搜   表面上是    40入口的bfs   但是除去有的数不是素数   入口数远小于40 可以写一个  判断一个数是否为素数的函数  , 每次去 调用 判断一个数是否要进队列 也可以 事先打一个素数表  这样会快点 注意:output  :either with a number stating the

poj 3984:迷宫问题(广搜,入门题)

迷宫问题 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7635   Accepted: 4474 Description 定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, }; 它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要

poj 3278 Catch That Cow(广搜)

Catch That Cow Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 45087   Accepted: 14116 Description Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,00