题意 : 真真是做POJ第一次遇到中文题,好吧,虽然语言通了,我一开始也没看懂样例什么意思,题意的话就是说这个探险家想娶酋长的女儿,但是没有钱,酋长说他可以用祭司的水晶球或者皮袄来换取少花一部分钱,同样的祭司也提出了类似的要求。最后输出能够花的最少的钱去迎娶酋长的女儿。

这个题需要注意的点是:1.等级问题,等级相差过大的话,不与探险家交换;

2.而每一个物件,编号自1到n是已经默认的,所以不用再去赋值或者迷惑了。。

思路 :就是一个最短路的问题,Dijkstra还有 Bellman ford 以及spfa都可以去求,不过倒是不知道为什么,大神们统一用的Dijkstra去做的,以致我一度认为这个题必须用这个做,后来问了秦老师,说是哪个都可以,本题是用的Dijkstra方法做的。其实就是把这个转化为一个图,建图就行了,不过应该注意的点是,每一个结点也是有值的,做的时候要别忘了加上再进行比较。

 #include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
const int maxn = ;
using namespace std;
const int oo =<<;
int map[maxn][maxn];//map数组里存的是整个图中每两个点之间那条边的权值
int dis[maxn];//dis数组里存的是每次更新的最小值
int vis[maxn];//标记数组,表示某个点是否已被访问
int m,n;//地位等级差距限制以及物品总数
int pric[maxn],l[maxn],coun;//每个物品的价值,物品主人的等级,这个物品的替代品数
int num,repl;//替代品的编号,优惠后的价格
int max1=oo;//初始化
int i,j,k,h; /*Dijkstra Algorithm*/
void dijkstra(int s)
{
memset(vis,,sizeof(vis));
for(k = ; k <= n ; k++)
dis[k] = oo;//初始化
dis[] = ;
for(k = ; k <= n ; k++)
{
int u,min = oo ;
for(j = ; j <= n ; j++)
{
if(!vis[j] && dis[j]<=min && l[j]<=s+m && l[j]>=s)//该点没被访问过,并且小于min,物品主人没有超出等级的限制
{
min = dis[j]; //双重循环在找每个dis的最小值
u = j;//记下这个点的下标以用于下边dis数组的更新
}
}
vis[u] = ;//标记结点已被访问
// if(min == oo)
// break;
for(j = ; j <= n ; j++)
{
if(l[j]>=s && l[j]<=s+m && map[u][j]!=oo && dis[j]>=dis[u]+map[u][j])
//没有超出等级限制,并且这两点是有边的,还满足比他小
{
dis[j] = dis[u]+map[u][j] ;//dis数组的更新
}
}
}
int c = pric[];
for(j = ; j <= n ; j++)
{
//因为每个节点本身是有值的,如果更新到某个结点再加上这个点物品的价值比原来那个点的钱还多,那就没有要换的必要了
if(dis[j]==oo)
continue;
if(dis[j]+pric[j] < c)
c = dis[j]+pric[j];
}
max1 = min(c,max1);
}
void init()
{
for(i = ; i <= n; i++)
for(j = ; j <= n ; j++)
map[i][j]=map[j][i]=oo;
}
int main()
{
while(~scanf("%d%d",&m,&n))
{
init();
for(i = ; i <= n ; i++)
{
scanf("%d %d %d",&pric[i],&l[i],&coun);
for(j = ; j <= coun ; j++)
{
scanf("%d %d",&num,&repl);
if(map[i][num]>repl)
map[i][num]=repl;
}
}
int s;
int s=max(l[]-m,);//筛选掉等级差别过大的那些等级
/*if(l[1]-m > 0)
s = l[1]-m;
else s = 0;*/
for(i=s; i<=l[]; i++)//每个点遍历一遍
dijkstra(i);
printf("%d\n",max1);
}
return ;
}

Dijkstra算法的话还算是比较好理解的,其基本步骤就是:

1、把所有结点分成两组:
      第一组:包括已经确定最短路径的结点;
      第二组:包括尚未确定最短路径的结点。
2、开始时,第一组只包含起点,第二组包含剩余的点;
3、用贪心的策略,按最短路径长度递增的顺序把第二组的结点加到第一组去,直到v0可达的所有结点都包含于第一组中。在这个过程中,不断更新最短路径,总保持从v0到第一组各结点的最短路径长度dist都不大于从v0到第二组任何结点的路径长度。
4、每个结点对应一个距离值,第一组结点对应的距离就是v0到此结点的最短路径长度,第二组结点对应的距离值就是v0由第一组结点到此结点的最短路径长度。
5、直到所有的顶点都扫描完毕(v0可达的所有结点都包含于第一组中),找到v0到其它各点的所有最短路径。

详细可以参考大神的博客http://www.cnblogs.com/mycapple/archive/2012/08/12/2634227.html,有图有字生动形象

这个是算法邻接表的模板,秦老师写的:

 #include <stdio.h>
#include <string.h> const int maxn = ;
const int maxm = ;
const int oo = <<;
struct node{
int u;
int v;
int w;
int next;
}edge[maxm];
int head[maxn];
int dis[maxn];
int cnt;
int n, m; void add(int u, int v, int w){
edge[cnt].u = u;
edge[cnt].v = v;
edge[cnt].w = w;
edge[cnt].next = head[u];
head[u] = cnt++;
} void dijkstra(int s){
bool vis[maxn];
for(int i = ; i < n; i++){
dis[i] = oo;
vis[i] = false;
}
dis[s] = ;
for(int i = ; i < n; i++){
int minn = oo;
int u = s;
for(int j = ; j < n; j++){
if(!vis[j] && minn > dis[j]){
minn = dis[j];
u = j;
}
}
for(int j = head[u]; j != -; j = edge[j].next){
int v = edge[j].v;
int newdis = minn + edge[j].w;
if(!vis[v] && newdis < dis[v]) dis[v] = newdis;
}
vis[u] = true;
}
} void init(){
cnt = ;
memset(head, -, sizeof(head));
} int main(){
while(~scanf("%d %d", &n, &m)){
int u, v, w;
init();
for(int i = ; i < m; i++){
scanf("%d %d %d", &u, &v, &w);
add(u, v, w);
add(v, u, w);
}
scanf("%d %d", &u, &v);
dijkstra(u);
if(dis[v] < oo) printf("%d\n", dis[v]);
else puts("-1");
}
return ;
}

这个代码是杭电1784的代码

 

POJ 1062 昂贵的聘礼(Dijkstra)的更多相关文章

  1. POJ - 1062 昂贵的聘礼 Dijkstra

    思路:构造最短路模型,抽象出来一个源点,这个源点到第i个点的费用就是price[i],然后就能抽象出图来,终点是1. 任意两个人之间都有等级限制,就枚举所有最低等级限制,然后将不再区间[min_lev ...

  2. 最短路(Dijkstra) POJ 1062 昂贵的聘礼

    题目传送门 /* 最短路:Dijkstra算法,首先依照等级差距枚举“删除”某些点,即used,然后分别从该点出发生成最短路 更新每个点的最短路的最小值 注意:国王的等级不一定是最高的:) */ #i ...

  3. POJ 1062 昂贵的聘礼(图论,最短路径)

    POJ 1062 昂贵的聘礼(图论,最短路径) Description 年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为聘礼才答应把女 ...

  4. poj 1062 昂贵的聘礼 (dijkstra最短路)

    题目链接:http://poj.org/problem?id=1062 昂贵的聘礼 Time Limit: 1000MS   Memory Limit: 10000K Total Submission ...

  5. POJ 1062 昂贵的聘礼(带限制条件的dijkstra)

    题目网址:http://poj.org/problem?id=1062 题目: 昂贵的聘礼 Time Limit: 1000MS   Memory Limit: 10000K Total Submis ...

  6. POJ - 1062 昂贵的聘礼(最短路Dijkstra)

    昂贵的聘礼 Time Limit: 1000MS Memory Limit: 10000KB 64bit IO Format: %I64d & %I64u SubmitStatus Descr ...

  7. POJ 1062 昂贵的聘礼

    C - 昂贵的聘礼 Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit St ...

  8. 最短路POJ 1062 昂贵的聘礼

    C - 昂贵的聘礼 Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit St ...

  9. POJ -1062 昂贵的聘礼(前向星 &amp;&amp; SPFA)

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u013497151/article/details/30299671 题目链接:id=1062&qu ...

  10. POJ 1062 昂贵的聘礼 (最短路)

    昂贵的聘礼 题目链接: http://acm.hust.edu.cn/vjudge/contest/122685#problem/M Description 年轻的探险家来到了一个印第安部落里.在那里 ...

随机推荐

  1. mysql主从复制-linux版本

    来自:http://www.osyunwei.com/archives/7269.html,改版 mysql主从复制本文采用的是centos6.5+mysql-5.6.23版本之前在 windows7 ...

  2. [大牛翻译系列]Hadoop(7)MapReduce:抽样(Sampling)

    4.3 抽样(Sampling) 用基于MapReduce的程序来处理TB级的数据集,要花费的时间可能是数以小时计.仅仅是优化代码是很难达到良好的效果. 在开发和调试代码的时候,没有必要处理整个数据集 ...

  3. 如何查看 Apache 的版本

    查看 Apache 服务器版本的命令行为: httpd -v 或者 apachectl -v 例如:用 Xshell 连接到服务器后,输入:httpd -v 或者:apachectl -v 返回: S ...

  4. php 图形验证码的3种方法

    生成图形验证码需要使用php GD库来生成,如果你没开户GD库我们需要在php.ini文件找到extension=php_gd2.dll 去掉前面的;就行了,然后重启apache 或iis环境即可 检 ...

  5. JS遇到的问题解决

    1.input 里使用onclick事件,整整花了1个半小时,onclick里面直接用Location.href不需要加<script></script> <?php / ...

  6. GoldenGate单向复制配置示例

    一:环境介绍 --source端 ip地址:192.168.123.10 数据库版本:11.2.0.1.0 32 bit 操作系统版本:centos 4.5 32 bit ogg版本:fbo_ggs_ ...

  7. 连续子数组的最大和/1007. Maximum Subsequence Sum (25)

    题目描述 HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但是,如果向量 ...

  8. 【css老版本浏览器兼容利器】ie-css3.htc

    做前端的同学都应该听说或者用过,是一段脚本,可以让ie实现css3里的圆角和阴影效果. css带来的便利是很容易感受的到的,但恶心的是它在ie下的不兼容,所以某位牛人现身写了个ie-css3.htc, ...

  9. 【C#】线程池

    将方法排入队列以便执行,并指定包含该方法所用数据的对象.此方法在有线程池线程变得可用时执行. class Program { static void Main(string[] args) { str ...

  10. Windows Form 分页。

    其实功能实现很简单.我做的是一个通用的分页控件.项目时间很紧,可能有点粗糙.欢迎大家斧正.不说了直接贴代码吧. using System; using System.Collections.Gener ...