码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 1062:昂贵的聘礼

时间:2015-08-04 22:56:21      阅读:98      评论:0      收藏:0      [点我收藏+]

标签:poj

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

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

自己想出来的思路并把这道题实现的时候特别兴奋。

这题注意两点:

1.把优惠的部分当作路径然后dijkstra,最后比较的是每个点的价值+那个点的最短路径长度。

2.记录进入set时的每个点的前面节点,为了比较level时使用,这个节点以及这个节点的前面节点都比较level之后通过才行。

代码:

#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <string>
#include <cstring>
#pragma warning(disable:4996)
using namespace std;

int MAX;
int edge[1005][1005];
int vist[1005],level[1005],minidis[1005],value[1005],pre[1005];
int level_diff,good_num;

void init()
{
	memset(edge,-1,sizeof(edge));
}
void init2()
{
	int i;
	for(i=1;i<=good_num;i++)
	{
		minidis[i]=MAX;
		pre[i]=1;
		vist[i]=0;
	}
}

void dijkstra(int i)
{
	int j,k;
	int position=i;

	vist[position]=1;
	minidis[position]=0;

	for(j=1;j<=good_num-1;j++)//一共要添加进num-1个点
	{
		for(k=1;k<=good_num;k++)
		{
			if(vist[k]==0 && abs(level[i]-level[k])<=level_diff && edge[position][k]!=-1 && minidis[position]+edge[position][k] < minidis[k])//新填入的点更新minidis
			{
				int flag=0,temp=position;
				while(temp!=1)
				{
					if(abs(level[temp]-level[k])>level_diff)
					{
						flag=1;
						break;
					}
					else
					{
						temp=pre[temp];
					}
				}
				if(flag==0)
				{
					minidis[k]=minidis[position]+edge[position][k];
					pre[k]=position;
				}
			}
		}
		int min_value=MAX,min_pos=0;
		for(k=1;k<=good_num;k++)
		{
			if(vist[k]==0 && minidis[k]<min_value)//比较出最小的那一个作为新添入的店
			{
				min_value = minidis[k];
				min_pos = k;
			}
		}

		vist[min_pos]=1;
		position=min_pos;
	}

}

int main()
{
	int i,j,replace;

	scanf("%d%d",&level_diff,&good_num);
	init();
	for(i=1;i<=good_num;i++)
	{
		scanf("%d%d%d",&value[i],&level[i],&replace);
		int temp;
		for(j=1;j<=replace;j++)
		{
			scanf("%d",&temp);
			scanf("%d",&edge[i][temp]);
		}
	}
	MAX=value[1];
	init2();

	dijkstra(1);
	int ans=MAX;

	for(i=1;i<=good_num;i++)
	{
		ans=min(ans,minidis[i]+value[i]);
	}

	cout<<ans<<endl;
	return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

POJ 1062:昂贵的聘礼

标签:poj

原文地址:http://blog.csdn.net/u010885899/article/details/47283491

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!