POJ 1062 昂贵的聘礼(Dijkstra)
题意 : 真真是做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)的更多相关文章
- POJ - 1062 昂贵的聘礼 Dijkstra
思路:构造最短路模型,抽象出来一个源点,这个源点到第i个点的费用就是price[i],然后就能抽象出图来,终点是1. 任意两个人之间都有等级限制,就枚举所有最低等级限制,然后将不再区间[min_lev ...
- 最短路(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 昂贵的聘礼(带限制条件的dijkstra)
题目网址:http://poj.org/problem?id=1062 题目: 昂贵的聘礼 Time Limit: 1000MS Memory Limit: 10000K Total Submis ...
- POJ - 1062 昂贵的聘礼(最短路Dijkstra)
昂贵的聘礼 Time Limit: 1000MS Memory Limit: 10000KB 64bit IO Format: %I64d & %I64u SubmitStatus Descr ...
- POJ 1062 昂贵的聘礼
C - 昂贵的聘礼 Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u Submit St ...
- 最短路POJ 1062 昂贵的聘礼
C - 昂贵的聘礼 Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u Submit St ...
- POJ -1062 昂贵的聘礼(前向星 && SPFA)
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u013497151/article/details/30299671 题目链接:id=1062&qu ...
- POJ 1062 昂贵的聘礼 (最短路)
昂贵的聘礼 题目链接: http://acm.hust.edu.cn/vjudge/contest/122685#problem/M Description 年轻的探险家来到了一个印第安部落里.在那里 ...
随机推荐
- KOBEV / KOBED
check the highlighted. the number of execution. if too high, can be the requirement was all met. whi ...
- 【风马一族_Android】Android学习
如果是色彩盲,请自行收藏这个网站:Material Design Color Palette Generator 所有书上的UI部分扫一遍就行了,我相信现在还没有书按material design标准 ...
- 让backspace键默认为删除键
在/root/.bashrc 中插入一条: stty erase ^H
- TOMCAT内存大小调整
Tomcat本身不能直接在计算机上运行,需要依赖于硬件基础之上的操作系统和一个java虚拟机.JAVA程序启动时JVM都会分配一个初始内存和最大内存给这个应用程序.这个初始内存和最大内存在一定程度都会 ...
- php解析url的三种方法举例
使用php解析url的三个示例. 方法一: $url="http://www.jbxue.com"; file_get_contents($url); 方法二: // CURL 方 ...
- html设置360兼容/极速模式
由于众所周知的情况,国内的主流浏览器都是双核浏览器:基于Webkit内核用于常用网站的高速浏览.基于IE的内核用于兼容网银.旧版网站.以360的几款浏览器为例,我们优先通过Webkit内核渲染主流的网 ...
- Django之Model(一)--基础篇
0.数据库配置 django默认支持sqlite,mysql, oracle,postgresql数据库.Django连接数据库默认编码使用UTF8,使用中文不需要特别设置. sqlite djang ...
- Microsoft AzureStorageAccount for Powershell
使用Powershell 创建的存储账户,注意StorageAccountName只能使用小写字母以及数字, -Location参考http://www.cnblogs.com/SignalTips/ ...
- EditPlus64的安装配置
下载地址,直接到360下载即可,下载完毕之后,进入如下网址,完后在线生成注册码 http://www.jb51.net/tools/editplus/ 以上是文本编辑器EditPlus的安装以及注册, ...
- 使用ab测试工具 进行并发测试
ab.exe -n1000 -c100 http://localhost:8067/api/todo/555e95feb301baa678141148 http://www.cnblogs.com/y ...