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

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

 
题解:DFS,一定是单向边....维护最大和最小两个等级参数,然后搜索时维护这两个等级参数,,如果某个点的level与最大或最小相差大于 m 就是肯定不行的。。然后即时更新min,max
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <math.h>
using namespace std;
typedef long long LL;
const int INF = ;
const int N = ;
int m,n;
int MIN;
int graph[N][N];
struct Node{
int v,level;
}node[];
bool vis[N]; void dfs(int u,int ans,int level1,int level2){
vis[u] = true;
MIN = min(ans+node[u].v,MIN);
for(int i=;i<=n;i++){
if(!vis[i]&&graph[u][i]<INF){
if(abs(node[i].level-level1)>m) continue;
if(abs(node[i].level-level2)>m) continue;
dfs(i,ans+graph[u][i],min(node[i].level,level1),max(level2,node[i].level));
vis[i] = false;
}
}
}
int main()
{
while(scanf("%d%d",&m,&n)!=EOF){
for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
graph[i][j] = INF;
if(i==j) graph[i][j] = ;
}
}
int LEVEL;
for(int i=;i<=n;i++){
int num;
scanf("%d%d%d",&node[i].v,&node[i].level,&num);
for(int j=;j<=num;j++){
int a,b;
scanf("%d%d",&a,&b);
graph[i][a] = min(b,graph[i][a]);
}
}
LEVEL = node[].level;
memset(vis,,sizeof(vis));
MIN = ;
dfs(,,LEVEL,LEVEL);
printf("%d\n",MIN);
}
return ;
}

还有一种方法就是枚举每一个点作为最大level进行dijkstra.

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <math.h>
using namespace std;
typedef long long LL;
const int INF = ;
const int N = ;
int m,n;
int MIN;
int graph[N][N];
struct Node{
int v,level;
}node[];
bool vis[N];
int low[N];
int dijkstra(){
int pos=;
for(int i=;i<=n;i++){
low[i] = node[i].v;
}
for(int i=;i<n;i++){
int MIN = INF;
for(int j=;j<=n;j++){
if(!vis[j]&&MIN>low[j]){
pos = j;
MIN = low[j];
}
}
vis[pos] = true;
for(int j=;j<=n;j++){
if(!vis[j]&&low[j]>low[pos]+graph[pos][j]){
low[j] = low[pos]+graph[pos][j];
}
}
}
return low[];
}
int main()
{
while(scanf("%d%d",&m,&n)!=EOF){
for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
graph[i][j] = INF;
if(i==j) graph[i][j] = ;
}
}
for(int i=;i<=n;i++){
int num;
scanf("%d%d%d",&node[i].v,&node[i].level,&num);
graph[][i] = node[i].v;
for(int j=;j<=num;j++){
int a,b;
scanf("%d%d",&a,&b);
graph[a][i] = min(b,graph[a][i]);
}
}
int LEVEL;
MIN = INF;
for(int i=;i<=n;i++){
LEVEL = node[i].level;///设当前值的level 最大
memset(vis,,sizeof(vis));
for(int j=;j<=n;j++){
if(node[j].level>LEVEL||LEVEL-node[j].level>m) vis[j] = true;
}
MIN = min(MIN,dijkstra());
}
printf("%d\n",MIN);
}
return ;
}

hdu 1062(DFS||dijkstra)的更多相关文章

  1. HDU 5143 DFS

    分别给出1,2,3,4   a, b, c,d个 问能否组成数个长度不小于3的等差数列. 首先数量存在大于3的可以直接拿掉,那么可以先判是否都是0或大于3的 然后直接DFS就行了,但是还是要注意先判合 ...

  2. Snacks HDU 5692 dfs序列+线段树

    Snacks HDU 5692 dfs序列+线段树 题意 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充, ...

  3. hdu 1142(DFS+dijkstra)

    #include<iostream> #include<cstdio> #include<cmath> #include<map> #include&l ...

  4. ACM: HDU 1869 六度分离-Dijkstra算法

    HDU 1869六度分离 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Descri ...

  5. HDU 5877 dfs+ 线段树(或+树状树组)

    1.HDU 5877  Weak Pair 2.总结:有多种做法,这里写了dfs+线段树(或+树状树组),还可用主席树或平衡树,但还不会这两个 3.思路:利用dfs遍历子节点,同时对于每个子节点au, ...

  6. HDU 1062 Text Reverse(水题,字符串处理)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1062 解题报告:注意一行的末尾可能是空格,还有记得getchar()吃回车符. #include< ...

  7. hdu 4751(dfs染色)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4751 思路:构建新图,对于那些两点连双向边的,忽略,然后其余的都连双向边,于是在新图中,连边的点是能不 ...

  8. HDU 1045 (DFS搜索)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1045 题目大意:在不是X的地方放O,所有O在没有隔板情况下不能对视(横行和数列),问最多可以放多少个 ...

  9. HDU 1241 (DFS搜索+染色)

    题目链接:  http://acm.hdu.edu.cn/showproblem.php?pid=1241 题目大意:求一张地图里的连通块.注意可以斜着连通. 解题思路: 八个方向dfs一遍,一边df ...

随机推荐

  1. thinkphp include处理加载重复出现的html页面

    在网站设计经常用大量使用的html模板,例如header(一般是menu层甚至还带有图片轮播).left(后台管理页面比较常见的导航).footer(结尾层,一般也是小型的menu),使用includ ...

  2. [luogu P1442] 铁球落地

    题目链接 线段树\(+dp\). 先用线段树预处理出每个线段从左边和右边掉落到哪里,记为\(f[i][0/1]\). 然后记\(g[i][0/1]\)为到达第\(i\)个线段的左边或右边所要的最小时间 ...

  3. 洛谷P4589 [TJOI2018]智力竞赛 【floyd + 二分 + KM】

    题目链接 洛谷P4589 题意可能不清,就是给出一个带权有向图,选出\(n + 1\)条链,问能否全部点覆盖,如果不能,问不能覆盖的点权最小值最大是多少 题解 如果要问全部覆盖,就是经典的可重点的DA ...

  4. BZOJ1143 [CTSC2008]祭祀river 【二分图匹配】

    1143: [CTSC2008]祭祀river Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 3236  Solved: 1651 [Submit] ...

  5. size用法小记

    By francis_hao    Feb 14,2017 列出二进制文件各个段的大小和总大小 概述 选项解释 -A -B --format=compatibility 选择显示的格式, -A = - ...

  6. oracle的rownum使用

    对于rownum来说它是Oracle系统顺序分配为从查询返回的行的编号,返回的第一行分配的是1,第二行是2,依此类推,这个伪字段可以用于限制查询返回的总行数,且rownum不能以任何表的名称作为前缀. ...

  7. 停止ambari上服务的顺序

    Before performing any upgrades or uninstalling software, stop all of the Hadoop services in the foll ...

  8. java实现极简的LRU算法

    import java.util.LinkedHashMap;import java.util.Map; /** * LRU (Least Recently Used)  */public class ...

  9. JS中this的指向问题(读书笔记纯手打~)

    一.this JavaScrip的this总是指向一个对象,而具体指向哪个对象是在运行时基于函数的执行环境动态绑定的,而非函数被声明时的环境. 二.this的指向 根据运用情景可分为四类: 1.作为对 ...

  10. 二进制转16进制JAVA代码

    public class Binary2Hex { public static void main(String[] args) { String bString ="10101000&qu ...