这道题大体上是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;
}