poj1062

这道题大体上是dijkstar,因为说是大体上,所以思考问题的时候很多地方都不会注意到,具体的注意事项已在代码中讲全。注意细节

/*金币最少问题
一种物品=另一种物品+金币;
由于他们的交换一直是要降低价格,也就是例如2.money+2——>4的交换价值为200是一定要小于4.money;
假设4——>2是存在的,则4.money+4——>2一定是小于2的,由于边上的权重都是正数,所以不可能出现环的状态;
同样的,包含有多个点的环也是不存在的,这是一个有向图,无环,所以必定存在一个点的入度为0,也就是说
其他所有的物品种类都不能交换改商品,把此点作为源点,1号点作为终点,有题目可知,则是求到终点的最短
路径,有没有负权重的边,所以用dijkstra算法解决即可。(后经思考得知这样的方法是不对的,正确的是下面
的方法)*/
/*对于所有的图算法,我所见到的就是单源最短路径,单源最短路径说明这个源点是显现出来的,但是这道题目
像是给了我一个隐藏的起始点,因为在原始的算法中,起始时间初始化的时候就是将邻接的边算进去,这道题目
首先每一个点都会有一个自身的金币数量,而不是无穷大,这相当于隐藏的初始化了第一步,可以看做是一个起点
于每条边都有链接,所以是n+1个点,找到每个点的最短路径需要循环n次,由于1号点可能在中途就被找到,所以要
提前结束算法。*/
/*对于有阶级差距的问题,最大应该是M,可以转换为区间问题,也就是在长度为M的区间内取值,对所有可能的
区间进行枚举,就可以达到答案*/
#include <iostream>
#define MAX 103
const int infinite=0x7fffffff;
using namespace std;

int dist[MAX],flag[MAX],level[MAX],ownPrice[MAX];
int diagram[MAX][MAX];
int realNumOfThings;
void dijkstra()
{
	for (int q=1;q<=realNumOfThings;q++)//每次开始都要初始化,避免在前一个M下生成的dist造成影响;
	{
		dist[q]=ownPrice[q];
	}
	//找到最短的边的点
	for (int i=1;i<=realNumOfThings;++i)
	{
		int node=0,min=1000000,cishu=0;
		for (int j=1;j<=realNumOfThings;j++)
		{
			if(!flag[j]&&dist[j]<min)
			{
				min=dist[j];
				node=j;cishu++;
			}
		}
		if(node==1)
			break;
		flag[node]=1;
		//松弛操作
		for (int k=1;k<=realNumOfThings;k++)
		{
			if(!flag[k]&&diagram[node][k]<infinite&&dist[node]+diagram[node][k]<dist[k])
				dist[k]=dist[node]+diagram[node][k];
		}
		
	}
}
int main()
{
	int distinctLevel,numOfThings;
	int price,levelOfThing,numOfInsteads;
	int indexOfInsteads,valueOfThing;
	int minLength=infinite;
	memset(diagram,1000000,sizeof(diagram));
	realNumOfThings=0;
	cin >> distinctLevel >> numOfThings;
	while (numOfThings--)
	{
		++realNumOfThings;
		cin >> price >> levelOfThing >> numOfInsteads;
		level[realNumOfThings]=levelOfThing;
		ownPrice[realNumOfThings]=dist[realNumOfThings]=price;
		while(numOfInsteads--)
		{
			cin >> indexOfInsteads >> valueOfThing;
			diagram[indexOfInsteads][realNumOfThings]=valueOfThing;
		}
	}
	for (int i=1;i<=realNumOfThings;i++)
	{
		//对区间进行枚举
		int minLevel=level[i];
		for (int j=1;j<=realNumOfThings;j++)
		{
			if(level[j]<minLevel||level[j]-minLevel>distinctLevel)
				flag[j]=1;
			else flag[j]=0;
		}
		dijkstra();
		if(dist[1]<minLength)
			minLength=dist[1];
	}
	cout << minLength << endl;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值