POJ 1062 dijkstra + 枚举

这题从下午七点做到晚上的九点半,才做出来。

题意,有一个人A,要去人B那里买东西,人B说了一个价格,然后说如果你能把人C的东西弄来,再加上一部分钱(比直接买人B东西的价格少),也能买到。

于是人A又去了人C那里,人C说了同上的话。依次类推。

但是这个交易圈子里有个规定,就是每个人都有一个等级,如果两个人相差k个等级以上,是不能产生直接或者间接交易的。

问最后你一定要买到人A的东西,最少要多少钱。

分析,分析过后,可以通过交易关系,A需要B的东西,将一条边由B连上A,建立有向图。如果没有等级制度,就是一个裸的dijkstra。存在等级制度加大了题目难度。一个比较简单的处理方法是,如果人A的等级为k,最后存在一条最短路。

那么最短路上的人的权值一定在区间 [k-m,k] [k-m+1,k+1] [k-m+2,k+2] ...... [k,k+m] 这些区间中。枚举区间范围,然后每个范围进行dijkstra,纪录最小答案。

注意细节问题就好。

 1 /* When all else is lost the future still remains. */
 2 /* You can be the greatest */
 3 #define rep(X,Y,Z) for(int X=(Y);X<(Z);X++)
 4 #define drep(X,Y,Z) for(int X=(Y);X>=(Z);X--)
 5 #define fi first
 6 #define se second
 7 #define mk(X,Y) make_pair((X),(Y))
 8 #define inf 0x3f3f3f3f
 9 #define clr(X,Y) memset(X,Y,sizeof(X))
10 #define pb push_back
11 //head
12 #include <iostream>
13 #include <stdio.h>
14 #include <queue>
15 #include <algorithm>
16 #include <string>
17 #include <map>
18 #include <string.h>
19 using namespace std;
20 #define maxN 110
21 vector<pair<int,int> > cur[maxN];
22 int val[maxN];
23 int lev[maxN];
24 int dis[maxN];
25 bool mark[maxN];
26 void init(int n){
27     rep(i,0,n+1) cur[i].clear();
28     clr(mark,0);
29     return ;
30 }
31 int find(int n){
32     int ans = -1;
33     int min_val = 2 * inf;
34     rep(i,1,n+1){
35         if(mark[i]) continue;
36         if(dis[i] < min_val){
37             min_val = dis[i];
38             ans = i;
39         }
40     }
41     return ans ;
42 }
43 int dij(int n , int m){
44     int ans = val[1];
45     rep(low,lev[1]-m,lev[1]+1){
46         int p;
47         int high = low + m;
48         rep(i,1,n+1) dis[i] = val[i];
49         clr(mark,0);
50         //
51         while((p = find(n)) != -1){
52             if(mark[1]) break;
53             //printf("%d \n",p);
54             //check(n);
55             mark[p] = 1;
56             if(lev[p] > high || lev[p] < low) continue;
57             int size = cur[p].size();
58             rep(i,0,size){
59                 int aim = cur[p][i].fi;
60                 int w = cur[p][i].se;
61                 if(lev[aim] < low || lev[aim] > high) continue;
62                 dis[aim] = min(dis[aim],dis[p] + w);
63             }
64         }
65         ans = min(ans,dis[1]);
66     }
67     return ans;
68 }
69 int main(){
70     int m , n;
71     while(~scanf("%d %d",&m,&n)){
72         init(n);
73         rep(i,1,n+1){
74             int w , l , num;
75             scanf("%d %d %d",&w,&l,&num);
76             val[i] = w; lev[i] = l;
77             rep(j,0,num){
78                 int a , b;
79                 scanf("%d %d",&a,&b);
80                 cur[a].pb(mk(i,b));
81             }
82         }
83         printf("%d\n",dij(n,m));
84     }
85     return 0;
86
87 }
时间: 2024-10-13 00:34:50

POJ 1062 dijkstra + 枚举的相关文章

昂贵的聘礼 - poj 1062 (Dijkstra+枚举)

Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 39976   Accepted: 11596 Description 年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为聘礼才答应把女儿嫁给他.探险家拿不出这么多金币,便请求酋长降低要求.酋长说:"嗯,如果你能够替我弄到大祭司的皮袄,我可以只要8000金币.如果你能够弄来他的水晶球,那么只要5000金币就行了.

昂贵的聘礼 poj 1062 Dijkstra

中文题,题意就不多说了,讲讲思路吧,先根据题意构图,与普通最短路不同的是这一题加了一个Rank,每个点都有一个Rank,题目要求最短路径上的点的Rank的最大差值在 M范围内,Dijkstra判断条件时加上Rank约束就行了.我没有添加汇点直接写的,另贴上别人添加汇点的写法. 我的代码: #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include

poj 1062 昂贵的聘礼 (dijkstra最短路)

题目链接:http://poj.org/problem?id=1062 昂贵的聘礼 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 36799   Accepted: 10616 Description 年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为聘礼才答应把女儿嫁给他.探险家拿不出这么多金币,便请求酋长降低要求.酋长说:"嗯,如果你能够替我弄到大祭司的

poj 1062 -- 昂贵的聘礼

昂贵的聘礼 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 35515   Accepted: 10163 Description 年 轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为聘礼才答应把女儿嫁给他.探险家拿 不出这么多金币,便请求酋长降低要求.酋长说:"嗯,如果你能够替我弄到大祭司的皮袄,我可以只要8000金币.如果你能够弄来他的水晶球,那么只要 5

【POJ 1062】 昂贵的聘礼

[POJ 1062] 昂贵的聘礼 附加一个小判断的最短路 这个题配得上这标题...有一个弯确实不好拐 反正我开始没想出来 然后居然水过去了!! 没错 POJ这数据... 很久前做的 最近根据计划训练又翻出来 看了看discussion 发现两组数据WA 重新想了想 改成了正规做法 其实就是由一号物品(首领物品/目标物品)的地位 向上 向下延伸出了一段可交易地位的范围 [level[1]-m, level[1]+m] 而要令一条路中所有点都符合条件 只需要每两点间距离不超过地位限制 即不断枚举区间

POJ -1062 昂贵的聘礼(前向星 &amp;&amp; SPFA)

题目链接:昂贵的聘礼 这个题对自己收获挺大的,模板要自己经常敲,才能理解,要自己经常敲,从能温故而知新,自己以前总结的建图方式,做题的时候要会用,要敢用,否则==NULL. 题意对于交换条件描述的有点不清楚,这里解释一下,假设8件物品,等级差距不能超过3,酋长LV 5,所以可以进行交换的LV区间是[2,5][3,6][4,7][5,8],不必考虑题目那一句,"但是如果他和某个地位较低的人进行了交易,地位较高的的人不会再和他交易,他们认为这样等于是间接接触,反过来也一样".越看越晕,只要

poj 1062 昂贵的聘礼 (最短路)

poj 1062 昂贵的聘礼 Description 年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为聘礼才答应把女儿嫁给他.探险家拿不出这么多金币,便请求酋长降低要求.酋长说:"嗯,如果你能够替我弄到大祭司的皮袄,我可以只要8000金币.如果你能够弄来他的水晶球,那么只要5000金币就行了."探险家就跑到大祭司那里,向他要求皮袄或水晶球,大祭司要他用金币来换,或者替他弄来其他的东西,他可以降低价格.探险家于是又跑到其他

poj 1062 昂贵的聘礼 解题报告

题目链接:http://poj.org/problem?id=1062 这一题只要想到如何建图,就不太难解决了.假设对于编号为 i 的物品,如果它得到物品 j 后价格从 pricei 降低到 pricej 的话,就用一个cost[i][j] = pricej.也就是从物品 i 到物品 j 连一条有向边.每一个编号的物品都这样处理,然后套用dijk 算法,求出从每个点出发的最短路,最终最小的那个就是答案.考虑到等级限制,别人可以跟酋长接触的前提是这个人的等级在 [ level 酋长-m  ~ le

poj 1062 (dij最短路径)

昂贵的聘礼 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 35968   Accepted: 10314 Description 年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为聘礼才答应把女儿嫁给他.探险家拿不出这么多金币,便请求酋长降低要求.酋长说:"嗯,如果你能够替我弄到大祭司的皮袄,我可以只要8000金币.如果你能够弄来他的水晶球,那么只要5000