Written by razrlele
14:48 August 22, 2014
昂贵的聘礼
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 41914 | Accepted: 12245 |
Description
年轻的探险家来到了一个印第安部落里。在那里他和酋长的女儿相爱了,于是便向酋长去求亲。酋长要他用10000个金币作为聘礼才答应把女儿嫁给他。探险家拿不出这么多金币,便请求酋长降低要求。酋长说:”嗯,如果你能够替我弄到大祭司的皮袄,我可以只要8000金币。如果你能够弄来他的水晶球,那么只要5000金币就行了。”探险家就跑到大祭司那里,向他要求皮袄或水晶球,大祭司要他用金币来换,或者替他弄来其他的东西,他可以降低价格。探险家于是又跑到其他地方,其他人也提出了类似的要求,或者直接用金币换,或者找到其他东西就可以降低价格。不过探险家没必要用多样东西去换一样东西,因为不会得到更低的价格。探险家现在很需要你的帮忙,让他用最少的金币娶到自己的心上人。另外他要告诉你的是,在这个部落里,等级观念十分森严。地位差距超过一定限制的两个人之间不会进行任何形式的直接接触,包括交易。他是一个外来人,所以可以不受这些限制。但是如果他和某个地位较低的人进行了交易,地位较高的的人不会再和他交易,他们认为这样等于是间接接触,反过来也一样。因此你需要在考虑所有的情况以后给他提供一个最好的方案。
为了方便起见,我们把所有的物品从1开始进行编号,酋长的允诺也看作一个物品,并且编号总是1。每个物品都有对应的价格P,主人的地位等级L,以及一系列的替代品Ti和该替代品所对应的”优惠”Vi。如果两人地位等级差距超过了M,就不能”间接交易”。你必须根据这些数据来计算出探险家最少需要多少金币才能娶到酋长的女儿。
为了方便起见,我们把所有的物品从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 2 3 4 5 6 7 8 9 |
1 4 10000 3 2 2 8000 3 5000 1000 2 1 4 200 3000 2 1 4 200 50 2 0 |
Sample Output
1 |
5250 |
Source
一道经典的图论题目, 虽然题目是用中文写的, 但是好像还是不怎么好读懂(天知道这题目要是换成英文该怎么破= =).
这道题就是有向图还带一点范围, 我用的是Bellman-Ford + 枚举.
首先要注意酋长的等级L, 等级最大差M, 初步就可以把交易范围锁定在[L-M, L+M], 但是还有一个问题就是, 就算保证所有的交易对象与酋长之间的等级差不超过M, 其他交易对象之间也有可能等级差也可以超标(比如酋长等级为3, 第一个交易对象为2, 第二个交易对象为2就不行), 所以这个地方可以从i=0开始一直到i=M, 依次枚举[L-M+i, L+i], 再用Bellman-Ford依次求出每个区间的最小值, 然后再比较即可, 跟着POJ讨论区的数据debug了好多次, 感觉有时间还是有必要重写一遍.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
/************************************************************************* > File Name: poj1062.cpp > Author: razrLeLe > Personal homepage: https://razrLeLe.com > Created Time: Wed 20 Aug 2014 07:41:35 AM CST ************************************************************************/ #include<iostream> using namespace std; #include<cstdio> #include<algorithm> #include<string.h> #define INF 0x3f3f3f3f struct points { int u, t;//u -> t int v; int l; }t[10010]; bool cmp(const points a, const points b) { return a.l < b.l; } int price[110], level[110]; int dis[110]; int countx, countp; int M, N; int P, L, X; int Q;//the level of boss int Queen; void Bellman_ford() { /*for(int i = 1; i < countp; i++) { cout << dis[i] << " "; }*/ //cout << endl; int min = INF; int p1 = 0, p2 = 0; for(int i = 0; i <= M; i++) { memset(dis, 0x3f, sizeof(dis)); dis[1] = Queen; // notice here, every time before bell-ford while(t[p1].l < Q-M+i) { p1 += 1; } // cout << endl <<Q-M+i << endl; while(t[p2].l <= t[p1].l+M) { p2 += 1; if(p2 == countx-1) { break; } } if(t[p2].l > t[p1].l + M) { p2 -= 1; } // cout << p1 << p2 << M << " " << countx-1 <<endl; // cout << p1 << endl << endl << t[p2].l << endl; for(int j = 0; j < N; j++) { bool flag = false; for(int k = p1; k <= p2; k++) { if(dis[t[k].t] > dis[t[k].u] - price[t[k].u]+t[k].v + price[t[k].t] && level[t[k].t] >= t[p1].l && level[t[k].t] <= t[p2].l ) { dis[t[k].t] = dis[t[k].u] - price[t[k].u] + price[t[k].t] + t[k].v; //cout << p1<<p2<<t[k].u << " "<< t[k].t << " " << dis[t[k].t] << endl; flag = true; } } if(!flag) break; } for(int j = p1; j <= p2; j++) if(min > dis[t[j].t]) { min = dis[t[j].t]; } if(p2 == countx-1) break; } printf("%dn", min); return ; } int main() { scanf("%d%d", &M, &N); countx = 0; countp = 1; for(int i = 1; i <= N; i++) { scanf("%d%d%d", &P, &L, &X); if(i == 1) { Q = L; Queen = P; } price[countp] = P; level[countp++] = L; if(X == 0) { t[countx].l = L; t[countx].u = i; t[countx].t = i; t[countx++].v = 0; } for(int j = 0; j < X; j++) { scanf("%d%d", &t[countx].t, &t[countx].v); t[countx].u = i; t[countx++].l = L; } } sort(t, t+countx, cmp); //for(int i = 0; i < countx; i++ ) // cout << t[i].l << " "; Bellman_ford(); return 0; } |