POJ1062 昂贵的聘礼 【DFS】

昂贵的聘礼

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

field=source&key=%E6%B5%99%E6%B1%9F" target="_blank" style="text-decoration:none">浙江

经典题。

#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;
}
时间: 2024-10-22 14:20:09

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

poj1062 昂贵的聘礼 (DFS)

A - 昂贵的聘礼 Crawling in process... Crawling failed Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 1062 Appoint description: System Crawler (2016-05-06) Description 年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了

poj1062昂贵的聘礼(Dijkstra**)

1 /* 2 题意: 物主有一个物品,价值为P,地位为L, 以及一系列的替代品Ti和该替代品所对应的"优惠"Vi 3 g[u][i] 表示的是u物品被i物品替换后的优惠价格!(u>0, i>0) 4 g[u][0]表示不用替换该物品的实际价格 ! 5 d[0]表示的是第一个物品经过一系列的物品替换之后的最少优惠价格! 6 7 思路:每当我们通过Dijkstra算法得到离源点(1)最近的距离的节点 p的时候(也就是1...pre[p], p)这条 8 路径上的物品互相替换后得

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

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

【日常学习】【条件最短路dij】POJ1062 昂贵的聘礼(2002年浙江省队选拔赛) 题解

耗时三节课 充分体现出粗心酿成大错这个道理 一开始一直不知道为什么数组越界 原来是minn和ninj写反了 后来又因为杜如函数出为题 反复调试 今后一定要注意 题目还是放上吧: 题目描述 Description 年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为聘礼才答应把女儿嫁给他.探险家拿不出这么多金币,便请求酋长降低要求.酋长说:"嗯,如果你能够替我弄到大祭司的皮袄,我可以只要8000金币.如果你能够弄来他的水晶球,那么只要5

poj1062——昂贵的聘礼(dijkstra变形)

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

POJ1062 昂贵的聘礼(带限制的spfa)

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

poj1062昂贵的聘礼

题目链接:http://poj.org/problem?id=1062 再一次被题意坑了,这次还是中文题...... 看的题解. 地位差距超过一定限制的两个人之间不会进行任何形式的直接接触,包括交易.他是一个外来人,所以可以不受这些限制.但是如果他和某个地位较低的人进行了交易,地位较高的的人不会再和他交易,他们认为这样等于是间接接触,反过来也一样.也就是说:同一条路径上的任意两个人,等级差不能超过M. 1 #include<cstdio> 2 #include<cstring> 3

POJ1062 昂贵的聘礼(最短路)

说白了就是给你一张图,每一个点有一个等级限制,在等级限制以内求一条最短路. 构图方法:首先将原点0连向每个物品相应的编号,那么边权为物品的初始价格:假设对于物品j,假设有了物品i,那么j的优惠价为w,就在i,j之间连一条权值为w的边.最后枚举等级的范围(注意等级的上下差为m,当中包括了酋长的等级,而不是与酋长等级差的绝对值小于等于m QAQ),求到原点到酋长(0号点到1号点)的最短路. #include<iostream> #include<cstdio> #include<

POJ1062 昂贵的聘礼 Dijkstra+枚举

http://poj.org/problem?id=1062 题目抽象 一张n个节点的带权有向图,每个节点都有一个值,问从各个点出发,到达0节点的最短路加上出发点的值的最小值是多少?(从0节点出发直接算作0号节点的值) 并且其中每个节点都有一个等级,在一条合法的最短路上不允许出现两个节点等级差大于给定值limit. 思路 弄了好久的题.和一般的最短路的区别是有一个limit限制.所以我们可以枚举最小等级,让每个节点的等级都试一下最小等级,然后再求最短路. 注意Dijkstra需要让不存在的边变成