/*
* poj 1062 昂贵的聘礼
数学模型:
图模型,物品与替代物品之间的单向关系采用有向边表示,各定点表示物品。
图的表示法: 邻接表法
解题思路:
单源点DFS遍历图,在给定的深度内找到最小的费用值。
这里与DFS有点不同的是:
采用回溯策略遍历图中所有的边组合,找出最小的费用值。
而DFS则在搜索的过程中发现某点已经访问过了,就不再搜索该点相关的出边了。
同时,可能会重复搜素某个点,因此该点搜索的最小值可以记录下来,DP或者记忆化搜素
最后再啰嗦句:
DFS是图的遍历方法,而回溯和状态空间搜素是策略思想,DFS采用回溯实现,回溯更基础。
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <list>
#include <algorithm>
namespace {
using namespace std;
typedef struct SUB_OBJ
{
int v;
int off_price;
}SUB_OBJ_S; // 替代品
typedef struct OBJ
{
int l;
int price;
}OBJ_S; // 物品
const int N_MAX = 100;
bool visited[N_MAX+1];
// 访问标记
OBJ_S V[N_MAX+1]; // 点集
list<SUB_OBJ_S> adj[N_MAX+1]; // 邻接表
int n, m;
// 给定的深度范围内找到最小的费用值,每次深度加深,该范围会随之变化
int dfs(int v, int level_bottom, int level_top)
{
int money = V[v].price;
visited[v] = true; // 进入置访问标志
for (list<SUB_OBJ_S>::iterator iter=adj[v].begin(); iter!=adj[v].end(); iter++)
{
// 该物品未被访问过,且物品的等级在允许范围内
if (!visited[iter->v] && (level_bottom<=V[iter->v].l && V[iter->v].l<=level_top))
{
int t = 0;
t= dfs(iter->v, max(level_bottom, V[iter->v].l-m), min(level_top, V[iter->v].l+m));
if (money > t+iter->off_price)
money = t+iter->off_price;
}
}
visited[v] = false; // 退出清空该标志
return money;
}
}
int main()
{
scanf("%d%d", &m, &n);
for (int i=1; i<=n; i++)
{
int x = 0;
scanf("%d%d%d", &V[i].price, &V[i].l, &x); // 建立点
SUB_OBJ_S stSubObj;
for (int j=0; j<x; j++)
{
scanf("%d%d", &stSubObj.v, &stSubObj.off_price);
adj[i].push_back(stSubObj); // 建立边
}
}
printf("%d\n", dfs(1, V[1].l-m, V[1].l+m));
return 0;
}
/*
测试数据1:
1 4
10000 3 2
2 8000
3 5000
1000 2 1
4 200
3000 2 1
4 200
50 2 0
5250
测试数据2:
1 5
10000 3 4
2 3000
3 2000
4 2000
5 9000
8000 2 3
3 5000
4 2000
5 7000
5000 1 0
2000 4 1
5 1900
50 1 0
4000
测试数据3:
3 8
10000 3 6
2 3000
3 2000
4 2000
5 9000
7 1000
8 5008
8000 2 3
3 5000
4 2000
5 7000
5000 1 1
6 1000
2000 4 1
5 1900
50 1 0
5000 1 1
7 4007
2000 4 1
5 1900
80 3 0
2950
测试数据4:
1 10
1324 0 0
1234 0 0
255 0 0
67 0 0
56 0 0
2134 0 0
456 0 0
2345 0 0
67 0 0
6436 0 0
1324
测试数据5:
1 4
10000 3 2
2 1
3 3
1000 2 2
4 1
3 1
1000 3 1
4 2
100 4 0
105
测试数据6:
3 5
10000 3 4
2 3000
3 2000
4 2000
5 9000
8000 2 3
3 5000
4 2000
5 7000
5000 1 0
2000 4 1
5 1900
50 1 0
3950
测试数据7:
0 5
10000 3 4
2 3000
3 2000
4 2000
5 9000
8000 2 3
3 5000
4 2000
5 7000
5000 4 0
2000 3 1
5 1900
50 2 0
4000
*/
poj 1062 昂贵的聘礼
最新推荐文章于 2024-09-14 22:25:22 发布