昂贵的聘礼
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 37475   Accepted: 10816

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

Source

经典题。

#include <stdio.h>
#include <stdlib.h>
#include <string.h> #define maxn 110
#define inf 0x3f3f3f3f struct Node {
int price, level, down;
} G[maxn];
int head[maxn], m, n, id;
struct Node2 {
int v, val, next;
} E[maxn * maxn];
bool vis[maxn];
int sta[maxn], id2; // sta防止间接等级越界 void addEdge(int u, int v, int val) {
E[id].v = v; E[id].next = head[u];
E[id].val = val; head[u] = id++;
} int min(int a, int b) {
return a < b ? a : b;
} int DFS(int u) {
for(int i = 0; i < id2; ++i)
if(abs(sta[i] - G[u].level) > m)
return inf;
int v, ans = G[u].price;
for(int i = head[u]; i != -1; i = E[i].next) {
if(vis[v = E[i].v]) return inf;
vis[v] = 1; sta[id2++] = G[u].level;
ans = min(ans, E[i].val + DFS(v));
vis[v] = 0; --id2;
}
return ans;
} int solve() {
memset(vis, 0, sizeof(bool) * (n + 1));
int i, j, v, ans = G[1].price; vis[1] = 1;
id2 = 0; sta[id2++] = G[1].level;
for(i = head[1]; i != -1; i = E[i].next) {
v = E[i].v;
ans = min(ans, E[i].val + DFS(v));
}
return ans;
} int main() {
int i, j, v, val;
while(scanf("%d%d", &m, &n) == 2) {
memset(head, -1, (n + 1) * sizeof(int));
for(i = 1, id = 0; i <= n; ++i) {
scanf("%d%d%d", &G[i].price, &G[i].level, &G[i].down);
for(j = 0; j < G[i].down; ++j) {
scanf("%d%d", &v, &val);
addEdge(i, v, val);
}
}
printf("%d\n", solve());
}
return 0;
}

2015.2.7更新

#include <stdio.h>
#include <string.h> #define inf 0x3f3f3f3f
#define maxn 110 struct Node {
int P, L, X; // 价格、主人等级、替代品数
} goods[maxn];
struct Node2 {
int T, V; // 编号、价格优惠
} substi[maxn][maxn];
int M, N;
bool vis[maxn]; int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; } int solve(int numOfGoods, int minLevel, int maxLevel)
{
if (maxLevel - minLevel > M) return inf;
int tempNumOfGoods, minL, maxL, i;
int result = goods[numOfGoods].P; for (i = 1; i <= goods[numOfGoods].X; ++i) {
tempNumOfGoods = substi[numOfGoods][i].T;
if (vis[tempNumOfGoods]) continue;
vis[tempNumOfGoods] = true;
minL = min(minLevel, goods[tempNumOfGoods].L);
maxL = max(maxLevel, goods[tempNumOfGoods].L);
result = min(result, solve(tempNumOfGoods, minL, maxL) + substi[numOfGoods][i].V);
vis[tempNumOfGoods] = false;
} return result;
} int main() {
// freopen("data.in", "r", stdin);
int i, j;
while (scanf("%d%d", &M, &N) == 2) {
memset(vis, 0, sizeof(vis));
for (i = 1; i <= N; ++i) {
scanf("%d%d%d", &goods[i].P, &goods[i].L, &goods[i].X);
for (j = 1; j <= goods[i].X; ++j)
scanf("%d%d", &substi[i][j].T, &substi[i][j].V);
} printf("%d\n", solve(1, goods[1].L, goods[1].L));
}
return 0;
}

2015.04.13更新

#include <stdio.h>
#include <string.h> const int maxn = 110;
const int inf = 0x3f3f3f3f;
int head[maxn], id;
struct Node {
int v, w, next;
} E[maxn*maxn];
struct Node2 {
int price, level;
} Per[maxn];
int N, M, dp[maxn]; // N articles int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; } void addEdge(int u, int v, int w)
{
E[id].v = v;
E[id].w = w;
E[id].next = head[u];
head[u] = id++;
} void getMap()
{
int i, j, P, L, K, w, v; memset(head, -1, sizeof(head));
memset(dp, 0, sizeof(dp)); for (id = 0, i = 1; i <= N; ++i) {
scanf("%d%d%d", &P, &L, &K);
Per[i].price = P;
Per[i].level = L;
while (K--) {
scanf("%d%d", &v, &w);
addEdge(i, v, w);
}
}
} int findMinCost(int k, int maxLevel, int minLevel)
{
maxLevel = max(maxLevel, Per[k].level);
minLevel = min(minLevel, Per[k].level);
if (maxLevel - minLevel > M)
return inf;
else if (dp[k]) return dp[k]; int ret = Per[k].price;
int i, v; dp[k] = Per[k].price;
for (i = head[k]; i != -1; i = E[i].next) {
v = E[i].v;
dp[k] = min(dp[k], findMinCost(v, maxLevel, minLevel) + E[i].w);
} return dp[k];
} int solve()
{
return findMinCost(1, Per[1].level, Per[1].level);
} int main()
{
while (~scanf("%d%d", &M, &N)) {
getMap();
printf("%d\n", solve());
}
return 0;
}

POJ1062 昂贵的聘礼 【DFS】的更多相关文章

  1. POJ-1062 昂贵的聘礼 (最短路)

    POJ-1062 昂贵的聘礼:http://poj.org/problem?id=1062 题意: 有一个人要到1号点花费最少的钱,他可以花费一号点对应的价格,也可以先买下其他一些点,使得费用降低. ...

  2. POJ1062昂贵的聘礼[最短路建模]

    昂贵的聘礼 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 45892   Accepted: 13614 Descripti ...

  3. [poj1062]昂贵的聘礼_最短路_离散化

    昂贵的聘礼 poj-1062 题目大意:原文链接?不是英文题,自己看 注释:$1\le N \le 100$. 想法:开始的想法有些过于简单,因为落下了一个条件:就是等级限制是一条路径上的任意两点而不 ...

  4. POJ1062昂贵的聘礼(dijkstra)

    昂贵的聘礼 题目大意是说有N个物品,每个物品都有自己的价格,但同时某些物品也可以由其他的(可能不止一个)替代品,这些替代品的价格比较“优惠”,问怎么样选取可以让你的花费最少来购买到物品1 由于有N个物 ...

  5. POJ1062昂贵的聘礼(经典) 枚举区间 +【Dijkstra】

    <题目链接>                   昂贵的聘礼 Description 年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用1000 ...

  6. poj1062 昂贵的聘礼

    Description 年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为聘礼才答应把女儿嫁给他.探险家拿不出这么多金币,便请求酋长降低 ...

  7. poj1062昂贵的聘礼(Dijkstra**)

    /* 题意: 物主有一个物品,价值为P,地位为L, 以及一系列的替代品Ti和该替代品所对应的"优惠"Vi g[u][i] 表示的是u物品被i物品替换后的优惠价格!(u>0, ...

  8. POJ1062 昂贵的聘礼(最短路)

    题目链接. 分析: 一开始以为简单的DFS,直接做,MLE了. 本体应该用最短路径(Dijkstra算法)做. 此题的关键在于等级限制的处理,采用枚举,即假设酋长等级为5,等级限制为2,那么需要枚举等 ...

  9. POJ-1062 昂贵的聘礼---Dijkstra+枚举上界

    题目链接: https://vjudge.net/problem/POJ-1062 题目大意: 中文题 思路: 1是终点,可以额外添加一个源点0,0到任意一节点的距离就是这个点的money,最终求的是 ...

随机推荐

  1. ssh生成密钥(供git使用)

    我们在使用git远程更新时候,需要设置好远程密钥,以使我们能够远程更新代码到代码库中.现在我们就来做一下这件事情(ssh模式下) ssh-keygen  -t rsa -c “hcu5555@hotm ...

  2. 5.7.2.4 random() 方法

    Math.random()方法返回大于等于0小于1的一个随机数.对于某些站点来说,这个方法非常实用,因为可以利用它来随机显示一些名人名言和新闻事件.套用下面的公式,就可以利用Math.random() ...

  3. Centos6.4 搭建Git服务器 (最简单的方法)

    下载 git-1.8.2.tar.gz tar -zvxf git-1.8.2.tar.gz cd git-1.8.2.2 sudo make prefix=/usr/local/git all su ...

  4. 中国 省会 地级市 经纬度 city array

    <?php $city_arr = array ( '北京' => array ( 'gis_lng' => '116.405285', 'gis_lat' => '39.90 ...

  5. SVN权限配置

    初始化SVN仓库后,里面有以下文件. 其中conf是对授权.认证进行管理的,conf目录里的内容有: passwd设立账户密码: authz权限管理: 假设pwd里有user1,user2两个账户 @ ...

  6. 深入剖析PE文件

    不赖猴的笔记,转载请注明出处. 深入剖析PE文件 PE文件是Win32的原生文件格式.每一个Win32可执行文件都遵循PE文件格式.对PE文件格式的了解可以加深你对Win32系统的深入理解. 一.   ...

  7. Cola:一个分布式爬虫框架 - 系统架构 - Python4cn(news, jobs)

    Cola:一个分布式爬虫框架 - 系统架构 - Python4cn(news, jobs) Cola:一个分布式爬虫框架 发布时间:2013-06-17 14:58:27, 关注:+2034, 赞美: ...

  8. Tomcat 的context.xml

    1. 在tomcat 5.5之前: --------------------------------------------------------------- Context体如今/conf/se ...

  9. oracle rman异机恢复

      Oracle源主机 Oracle目标主机 主机平台 CentOS6.2(final) CentOs6.2(FInal) 主机名 vick rman IP地址 192.168.1.11 192.16 ...

  10. Java中public,private,final,static等概念的解读

    作为刚入门Java的小白,对于public,private,final,static等概念总是搞不清楚,到底都代表着什么,这里做一个简单的梳理,和大家分享,若有错误请指正,谢谢~ 访问权限修饰符 pu ...