POJ 1062 昂贵的聘礼 最短路+超级源点
Description
为了方便起见,我们把所有的物品从1开始进行编号,酋长的允诺也看作一个物品,并且编号总是1。每个物品都有对应的价格P,主人的地位等级L,以及一系列的替代品Ti和该替代品所对应的"优惠"Vi。如果两人地位等级差距超过了M,就不能"间接交易"。你必须根据这些数据来计算出探险家最少需要多少金币才能娶到酋长的女儿。
Input
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
分析
输出最小的金币数,这道题首先想到的就是建图跑最小路,我最开始用的方法是根据所给信息把边权和点权都加上,然后在跑Dij的时候判断
如果选择边权,那么还要加和这个点的儿子的权,如果选择点权就不用,然后统计到各个点最小距离。
打了一下样例没过,然后回去想,发现加的是双向边,于是又加了一个vis数组判断是否访问过,这次样例过了,交上去WA
再仔细想一下,先不管我的点权和边权处理有没有问题,就一个问题是很难解决的,就是终点是什么,不一定所有的点都能当做本次统计的终点
也就是说它会直接返回最小值,不管这个最小值是不是已经把所有需要的点权边权都包括进去了,比如我要买二号物品来降低一号物品价格,在统计
到二号物品的路程时,直接返回了边权,但点权也是应该加上的,所以没有选完全 我感觉还是我的程序有问题
重新思考,有没有一种方法能够让程序自动判断选择边权还是点权,并且终点是一样的?
受如果使用该物品的话边权和点权必选其一的启发,我们可以采用超级源点,即把所有的点的点权作为这个点和超级源点的边权,于是又跑一遍
又没过样例,这次我发现一个问题,我加的是双向边,而加双向边是肯定不行的,因为边权表示买二号物品得到三号物品的优惠,如果加双向的话就
表明买三号物品也能得到二号物品的优惠,这显然是不对的,于是我们考虑边的方向,从源点出来,边的去向一定是指向每个点,因为我们是以源点
为起点,一号物品为终点跑的Dij,所以输入时,如果买a对b有优惠,那么Add_Edge(a->b),这样就可以保证终点是一样的,且最短路径上每个点的
点权或边权都被选完全了。
修改完代码,测了测样例,对了!然后交上去,WA。。。。
接着我思考半天后找到了我最开始过深考虑的问题——等级,我起初是怎么处理的呢?我在建图时判断,如果一个点的等级与第一物品的差值的
绝对值小于m,就不加这个点及其周围的边。这么看好像是对的,举个例子,m=3,level[1]=8,我们买了level[2]=6,level[3]=10的两个物品,由题意,
这不被允许,所以不能这么判断,但这给了我一个启发:买的物品价值范围(levelmax-levelmin<=m),所以我们可以考虑枚举物品的价值范围,每次
对于枚举的范围进行Dij求最短路,输出最短的路径即可。
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int N=,INF=0x3f3f3f3f;
struct Edge{
int to,next,val;
}e[N*N];
struct Node{
int id,val;
Node(){};
Node(int a,int b){id=a;val=b;}
bool operator < (const Node&A)const {
return val>A.val;
}
};
int Head[N],len,lev[N],ans,m,n,dis[N];
void Ins(int a,int b,int c){
e[++len].to=b;e[len].val=c;
e[len].next=Head[a];Head[a]=len;
}
void dij(int level){
priority_queue<Node> q;
memset(dis,0x3f,sizeof(dis));
dis[]=;
q.push(Node(,dis[]));
while(!q.empty()){
Node u=q.top();q.pop();
for(int x=Head[u.id];x;x=e[x].next){
int v=e[x].to;
if(lev[v]-level>m||lev[v]<level)continue;
if(dis[v]>dis[u.id]+e[x].val){
dis[v]=dis[u.id]+e[x].val;
q.push(Node(v,dis[v]));
}
}
}
ans=min(ans,dis[]);
}
int main(){
// freopen("a.txt","r",stdin);
int selfval;
ans=INF;
scanf("%d%d",&m,&n);
for(int i=;i<=n;i++){
int c;
scanf("%d%d%d",&selfval,&lev[i],&c);
Ins(,i,selfval);
for(int j=;j<=c;j++){
int a,b;
scanf("%d%d",&a,&b);
Ins(a,i,b);
}
}
for(int i=lev[]-m;i<=lev[];i++)
dij(i);
printf("%d\n",ans);
}
Code
这个问题看起来还是比较难的,但是想明白以后也比较简单,下次在做题的时候一定把问题先想清楚,边做边想太难了。。。。。。
POJ 1062 昂贵的聘礼 最短路+超级源点的更多相关文章
- POJ - 1062 昂贵的聘礼(最短路Dijkstra)
昂贵的聘礼 Time Limit: 1000MS Memory Limit: 10000KB 64bit IO Format: %I64d & %I64u SubmitStatus Descr ...
- POJ 1062 昂贵的聘礼 最短路 难度:0
http://poj.org/problem?id=1062 #include <iostream> #include <cstring> #include <queue ...
- poj 1062 昂贵的聘礼 最短路 dijkstra
#include <cstdio> #include <cmath> #include <cstring> #include <ctime> #incl ...
- 最短路(Dijkstra) POJ 1062 昂贵的聘礼
题目传送门 /* 最短路:Dijkstra算法,首先依照等级差距枚举“删除”某些点,即used,然后分别从该点出发生成最短路 更新每个点的最短路的最小值 注意:国王的等级不一定是最高的:) */ #i ...
- POJ 1062 昂贵的聘礼(图论,最短路径)
POJ 1062 昂贵的聘礼(图论,最短路径) Description 年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为聘礼才答应把女 ...
- poj 1062 昂贵的聘礼 (dijkstra最短路)
题目链接:http://poj.org/problem?id=1062 昂贵的聘礼 Time Limit: 1000MS Memory Limit: 10000K Total Submission ...
- 最短路POJ 1062 昂贵的聘礼
C - 昂贵的聘礼 Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u Submit St ...
- POJ 1062 昂贵的聘礼 (最短路)
昂贵的聘礼 题目链接: http://acm.hust.edu.cn/vjudge/contest/122685#problem/M Description 年轻的探险家来到了一个印第安部落里.在那里 ...
- POJ 1062 昂贵的聘礼 【带限制的最短路/建模】
年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为聘礼才答应把女儿嫁给他.探险家拿不出这么多金币,便请求酋长降低要求.酋长说:" ...
随机推荐
- Redis list实现原理 - 双向循环链表
双向链表 双向表示每个节点知道自己的直接前驱和直接后继,每个节点需要三个域 查找方向可以是从左往右也可以是从右往左,但是要实现从右往左还需要终端节点的地址,所以通常会设计成双向的循环链表; 双向的循环 ...
- Go-数据类型以及变量,常量,函数,包的使用
Go-数据类型以及变量,常量,函数,包的使用 一.数据类型 1.字符串类型 string -双引号包裹的:"xxx" -反引号包裹,可以换行, 注意: 区别于python,是没有单 ...
- 从0开发3D引擎(十):使用领域驱动设计,从最小3D程序中提炼引擎(上)
目录 上一篇博文 下一篇博文 前置知识 回顾上文 最小3D程序完整代码地址 通用语言 将会在本文解决的不足之处 本文流程 解释本文使用的领域驱动设计的一些概念 本文的领域驱动设计选型 设计 引擎名 识 ...
- TOMCAT封装DBCP
## 数据源 ## #Tomcat封装的DBCP: >> 基本知识: tomcat在默认情况下已经集成了DBCP: >> JNDI: |-- 基本概念: 在tomcat启动的时 ...
- 手写node可读流之流动模式
node的可读流基于事件 可读流之流动模式,这种流动模式会有一个"开关",每次当"开关"开启的时候,流动模式起作用,如果将这个"开关"设置成 ...
- echarts实现饼图及横向柱状图的绘制
项目中需要绘制饼图,因此简单学习了下echarts的基本使用.head中引入js文件: <script src="/static/frame/echarts/echarts.min.j ...
- 《深入理解 Java 虚拟机》读书笔记:虚拟机类加载机制
正文 虚拟机把描述类的数据从 Class 文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的 Java 类型,这就是虚拟机的类加载机制. 一.类加载的时机 1.类的生命 ...
- iTerm2 都不会用,还敢自称老司机?(上)
对于需要长期与终端打交道的工程师来说,拥有一款称手的终端管理器是很有必要的,对于 Windows 用户来说,最好的选择是 Xshell,这个大家都没有异议.但对于 MacOS 用户来说,仍然毋庸置疑, ...
- 网络|N1盒子做旁路由刷OpenWRT系统(小白专用)
N1盒子做旁路由刷OpenWRT系统(小白专用) 为什么要用N1盒子 现如今新上市的路由器,市面上能买到的300元以内的路由器大多数都是双频(5G Hz和2.4G Hz)和几年前相比无论是速度还是性能 ...
- Go语言转义字符
\a 匹配响铃符 (相当于 \x07) 注意:正则表达式中不能使用 \b 匹配退格符,因为 \b 被用来匹配单词边界, 可以使用 \x08 表示退格符. \f 匹配换页符 (相当于 \x0C) \t ...