POJ - 1062 昂贵的聘礼
題目鏈接
Description
年輕的探險(xiǎn)家來(lái)到了一個(gè)印第安部落里。在那里他和酋長(zhǎng)的女兒相愛(ài)了,于是便向酋長(zhǎng)去求親。酋長(zhǎng)要他用10000個(gè)金幣作為聘禮才答應(yīng)把女兒嫁給他。探險(xiǎn)家拿不出這么多金幣,便請(qǐng)求酋長(zhǎng)降低要求。酋長(zhǎng)說(shuō):”嗯,如果你能夠替我弄到大祭司的皮襖,我可以只要8000金幣。如果你能夠弄來(lái)他的水晶球,那么只要5000金幣就行了。”探險(xiǎn)家就跑到大祭司那里,向他要求皮襖或水晶球,大祭司要他用金幣來(lái)?yè)Q,或者替他弄來(lái)其他的東西,他可以降低價(jià)格。探險(xiǎn)家于是又跑到其他地方,其他人也提出了類似的要求,或者直接用金幣換,或者找到其他東西就可以降低價(jià)格。不過(guò)探險(xiǎn)家沒(méi)必要用多樣?xùn)|西去換一樣?xùn)|西,因?yàn)椴粫?huì)得到更低的價(jià)格。探險(xiǎn)家現(xiàn)在很需要你的幫忙,讓他用最少的金幣娶到自己的心上人。另外他要告訴你的是,在這個(gè)部落里,等級(jí)觀念十分森嚴(yán)。地位差距超過(guò)一定限制的兩個(gè)人之間不會(huì)進(jìn)行任何形式的直接接觸,包括交易。他是一個(gè)外來(lái)人,所以可以不受這些限制。但是如果他和某個(gè)地位較低的人進(jìn)行了交易,地位較高的的人不會(huì)再和他交易,他們認(rèn)為這樣等于是間接接觸,反過(guò)來(lái)也一樣。因此你需要在考慮所有的情況以后給他提供一個(gè)最好的方案。
為了方便起見(jiàn),我們把所有的物品從1開(kāi)始進(jìn)行編號(hào),酋長(zhǎng)的允諾也看作一個(gè)物品,并且編號(hào)總是1。每個(gè)物品都有對(duì)應(yīng)的價(jià)格P,主人的地位等級(jí)L,以及一系列的替代品Ti和該替代品所對(duì)應(yīng)的”優(yōu)惠”Vi。如果兩人地位等級(jí)差距超過(guò)了M,就不能”間接交易”。你必須根據(jù)這些數(shù)據(jù)來(lái)計(jì)算出探險(xiǎn)家最少需要多少金幣才能娶到酋長(zhǎng)的女兒。
Input
輸入第一行是兩個(gè)整數(shù)M,N(1 <= N <= 100),依次表示地位等級(jí)差距限制和物品的總數(shù)。接下來(lái)按照編號(hào)從小到大依次給出了N個(gè)物品的描述。每個(gè)物品的描述開(kāi)頭是三個(gè)非負(fù)整數(shù)P、L、X(X < N),依次表示該物品的價(jià)格、主人的地位等級(jí)和替代品總數(shù)。接下來(lái)X行每行包括兩個(gè)整數(shù)T和V,分別表示替代品的編號(hào)和”優(yōu)惠價(jià)格”。
Output
輸出最少需要的金幣數(shù)。
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
思路
- 數(shù)據(jù)小可用dfs,枚舉每一個(gè)狀態(tài)
- 構(gòu)建Dijkstra,關(guān)鍵是解決:交易群體的等級(jí)差小于M,這里用模擬區(qū)間的辦法解決,應(yīng)為最終都是到1,所以枚舉[ level[1] - M, level[1] ] ~~ [ level[1], level[1] + M ]
AC
// Dijkstra // #include <bits/stdc++.h> #include <iostream> #include <stdio.h> #include <string.h> #include <cmath> #include <vector> #define mem(a, b) memset(a, b, sizeof(a)) #define P pair<int, int> #define N 105 using namespace std; int inf = 0x3f3f3f3f; int n, m, vis[N], dis[N], price[N], level[N]; vector<P> ve[N]; int Dijkstra(int x, int min_l, int max_l) {mem(dis, inf);mem(vis, 0);dis[1] = 0;for (int i = 1; i <= n; i++) {int MIN = inf, u = -1;for (int j = 1; j <= n; j++) {if (vis[j] || level[j] < min_l || level[j] > max_l)continue;if (MIN > dis[j]) {MIN = dis[j];u = j;}}if (u == -1)break;vis[u] = 1;for (int j = 0; j < int(ve[u].size()); j++) {P t = ve[u][j];if (vis[t.first] || level[t.first] < min_l || level[t.first] > max_l)continue;if (dis[t.first] > MIN + t.second) {dis[t.first] = MIN + t.second;}}}int ans = inf;for (int i = 1; i <= n; i++) {if (price[i] + dis[i] < ans) {ans = price[i] + dis[i];}}return ans; } int main(){// freopen("in.txt", "r", stdin);scanf("%d%d", &m, &n);for (int i = 1; i <= n; i++) {int x;scanf("%d%d%d", &price[i], &level[i], &x);for (int j = 0; j < x; j++) {int a, b;scanf("%d%d", &a, &b);ve[i].push_back(make_pair(a, b));}}int ans = inf;for (int i = 0; i <= m; i++) {int temp = Dijkstra(1, level[1] - m + i, level[1] + i);ans = min(temp, ans);}printf("%d\n", ans);return 0; } // dfs // #include <bits/stdc++.h> #include <iostream> #include <stdio.h> #include <string.h> #include <cmath> #include <vector> #define mem(a, b) memset(a, b, sizeof(a)) #define P pair<int, int> #define N 105 using namespace std; int inf = 0x3f3f3f3f; struct ac{int d, l, num; }stuff[N]; int vis[N], n, m; vector<ac> ve[N]; int ans = 0; void solve(int x, int min_l, int max_l, int sum) {// printf("x = %d, min_l = %d, max_l = %d, sum = %d, ans = %d\n", x, min_l, max_l, sum, ans);if (ans > sum + stuff[x].d) ans = sum + stuff[x].d;for (int i = 0; i < int(ve[x].size()); i++) {ac t = ve[x][i];int min_ll = min(min_l, stuff[t.num].l);int max_ll = max(max_l, stuff[t.num].l);if (!vis[t.num] && max_ll - min_ll <= m) {vis[t.num] = 1;solve(t.num, min_ll, max_ll, sum + t.d);vis[t.num] = 0;}} }int main(){// freopen("in.txt", "r", stdin);scanf("%d%d", &m, &n);for (int i = 1; i <= n; i++) {int x;scanf("%d%d%d", &stuff[i].d, &stuff[i].l, &x);for (int j = 0; j < x; j++) {ac t;scanf("%d%d", &t.num, &t.d);ve[i].push_back(t);}}mem(vis, 0);vis[1] = 1;ans = inf;solve(1, stuff[1].l, stuff[1].l, 0);printf("%d\n", ans);return 0; }總結(jié)
以上是生活随笔為你收集整理的POJ - 1062 昂贵的聘礼的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 网络流 (EK Dinic)
- 下一篇: P1020 导弹拦截(最长不上升序列+二