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个金币作为聘礼才答应把女儿嫁给他.探险家拿不出这么多金币,便请求酋长降低要求.酋长说:" ...
随机推荐
- C++走向远洋——52(十三周阅读程序)
*/ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...
- dubbo与trivial超时机制的深入思考
说在前面 trivial是根据之前设计的RPC框架而来的(还在增进当中),其中较为不同的一个点为,在客户端去掉了业务线程池,因为既然都要等待,不必要再加一层. 进入正题 有在网上看到这样的信息,“之前 ...
- 【视频+图文】带你快速掌握带continue语句的双重for循环
双重for循环掌握后,我们就一起来看看双重for循环的进阶内容一之带continue语句的双重for循环. 上期双重for循环[视频+图文]讲解传输门:点击这里可去小乔的哔哩哔哩观看for循环视频~ ...
- APM监控工具Pinpoint搭建
一:Pinpoint简介与架构图示 Pinpoint是什么Pinpoint是开源在github上的一款使用JAVA语言编写的APM监控工具,用于大规模分布式系统监控.它对性能的影响较小,只增加约3%的 ...
- C与ARM汇编结合实现mini2440串口uart简单程序
最近学完了ARM的一些基础知识,开始在mini2440上开发一些简单的程序,串口发送程序是一开始涉及多个寄存器的例子,稍有繁多的步骤应该是开发过程中要慢慢适应的境况 下面的程序的目的是实现mini24 ...
- C++冒险攻略(持续更新中。。。)
C++语言程序设计 我的C++冒险之旅 绪论 计算机系统基本概念 计算机硬件 计算机程序语言 计算机解决问题是程序控制的 程序就是操作步骤 程序要使用语言来表达 机器语言 计算机能识别的是机器语言 机 ...
- Python之接口测试(一)
前言 之前我们已经学会了利用JMeter工具进行接口测试,今天我们学习一下如何利用python进行接口测试. 一:发送get请求 import requests,json url = 'http:// ...
- C#版免费离线人脸识别——虹软ArcSoft V3.0
[温馨提示] 本文共678字(不含代码),8张图.预计阅读时间需要6分钟. 1. 前言 人脸识别&比对发展到今天,已经是一个非常成熟的技术了,而且应用在生活的方方面面,比如手机.车站.天网等. ...
- HTTPS 笔记
随着互联网的迅速发展,网络安全问题日益凸显,现在 Chrome 浏览器已经开始阻止非 https 网站的访问了.对于 https 的流程一直不是十分清晰,借着还没有完全复工有时间,大概画了个图总结一下 ...
- 置顶,博客中所有源码 github
所有项目源代码,开源地址. 作者 github 主页 https://github.com/nejidev 目前开源项目有: 1, linux tea5767 at24c08 mmap 实现fm 收音 ...