Tom, a young explorer, visited an Indian tribe and fell in love with the Chief's daughter. Tom asked the Chief to marry his daughter to him. But the Chief would accept his proposal only if he could provide 10000 golden coins as the engagement gift. Tom couldn't make it, so he pled for a reduction. The Chief said:" OK, I would then request 8000 golden coins if you could get me the fur coat of the Pontiff. Or, if you could get me his crystal, I could drop to 5000 golden coins."
Tom then went to the Pontiff for his fur coat or crystal. The Pontiff too requested some amount of golden coins as the exchange, or a possible reduction of price if Tom could get him some other things. Tom continued to visit other people and found that all of them would either request some golden coins for exchange, or drop the price down for something else.
Now Tom needs your help on trading to marry the girl he loves.
An important rule Tom has to tell you is: the hierachical system is so strict in this tribe that two people will never contact each other in any way if the difference of the two levels they belong to is larger than a certain threshold. Tom is an outsider so he is beyond this restriction. However, if he trades with someone in a lower level, then others in a higher level will not trade with him anymore since otherwise they would be indirectly contacting the lower levels, and vice versa. Therefore your best suggestion to him must have all the situations considered.
For the sake of convenience, let us mark all the trading objects by numbers starting from 1. The Chief's approval is as well considered an object and is always marked 1. Each object has a price P, the owner's level L, and a sequence of substitutions Ti and the corresponding "voucher" price Vi. There must be no "indirect trading" if the difference between two levels is greater than M. You must calculate the least number of golden coins Tom needs to marry the daughter of the Chief.
Input
The input consists of several test cases. For each test case:
The 1st line contains two integers M and N (1<=N<=100) which represent the threshold of level difference and the total number of trading objects respectively.
Then the descriptions of N objects follow, in the increasing order with respect to their marks. Each description begins with three nonnegative integers P, L, and X (<N), representing the object's price, owner's level, and the number of substitutions. The following X lines each contains two integers T and V, which are the mark number of the substitution and its "voucher" price, respectively.
Output
For each test case, print in a single line the minimum number of golden coins needed.
Sample Input
1 4 10000 3 2 //The Chief's approval 2 8000 3 5000 1000 2 1 //The Pontiff's fur coat 4 200 3000 2 1 //The Pontiff's crystal 4 200 50 2 0 //Another object
Sample Output
5250题意:有n个点,输入路径间的原权值、等级和优惠后的权值,让求出到顶点1的最短路径即最小权值,从一个点出发,只能访问等级和它相等或者等级低于它但是不低于所给差值。
思路:在此题中,如果没有等级限制,我们可以直接套用dijstra模板,但是由于有了等级的限制,我们就得枚举每一个点,每次将该点能访问的所有点标记为0,再套用dijstra模板。要求出到目标点1的最短路径,在每次枚举一个点i后将求出的到目标点i的最短路minprice和之前的最短路径mprice进行比较,如果前者更小,则更新。
总结:单纯从题面来看,如果之前没有写过类似的题目,是根本不会想到可以用dijstra解决,自己知识的局限性导致看到这种题整个人就直接认怂看了题解,其实这样对自己的思维拓展很不好,虽然再给自己半天时间也肯定想不出来,但是,至少我用了时间去思考,也算是一种收获,还是比较赞同wdy的学习方法,先用自己的手段去尝试解决,如果实在不行再看题解,感觉这种练习方式培养了比赛场上的胆量,总比我这种连想都不敢想的人好很多,毕竟有时候就是看谁的脑洞开的更大~~so ,花了这么大篇幅写总结,希望下一题能看到有自己的思考在里面~~~
//枚举每个可行点,调用dijstra函数,算出最短路径
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
#define inf 0x3f3f3f3f
#define N 100
int price[N+10][N+10],dis[N+10],book[N+10],n;
struct node{
int label,vprice;//替代品,优惠后的价格
};
struct Node{
int p,l,s;//原价格,等级,替代品数
struct node num[N+10];//存储各个替代品
}vis[N+10];
int dijstra()
{
int u,maxprice;
memset(dis,inf,sizeof(dis));
for(int i = 1; i <= n; i ++)
dis[i] = price[0][i];//存储源点到各个点的原价格
for(int i = 1; i <= n; i ++)
{
maxprice = inf;
for(int j = 1; j <= n; j ++)
{
if(!book[j]&&dis[j] < maxprice)
{
maxprice = dis[j];
u = j;
}
}
book[u] = 1;//价格最少的物品u
for(int j = 1; j <= n; j ++)
{
if(!book[j]&&dis[j] > (dis[u]+price[u][j]))
dis[j] = dis[u] + price[u][j];
}
}
return dis[1];//返回源点到目标点的最低价格
}
int main()
{
int differ,minprice,mprice;
while(scanf("%d%d",&differ,&n)!=EOF)
{
for(int i = 0; i <= n; i ++)//初始化
{
for(int j = 0; j <= n; j ++)
if(i == j)
price[i][j] = 0;
else
price[i][j] = inf;
}
memset(book,0,sizeof(book));//标记点
for(int i = 1; i <= n; i ++)
{
scanf("%d%d%d",&vis[i].p,&vis[i].l,&vis[i].s);//读入原价格,等级,替代品数
price[0][i] = vis[i].p ;//源点到当前物品i的路径原价格
for(int j = 1; j <= vis[i].s ; j ++)
{
scanf("%d%d",&vis[i].num[j].label,&vis[i].num[j].vprice);//读入替代品和优惠后的价格
price[vis[i].num[j].label][i] = vis[i].num[j].vprice ;//price数组存储替代品到当前物品的优惠价格
}
}
mprice = inf;
for(int i = 1; i <= n; i ++)//枚举路径上每个点
{
//找到所有可行点,并且标记为0
for(int j = 1; j <= n; j ++)
{
if(vis[i].l<vis[j].l||vis[i].l-vis[j].l > differ)//如果其它物品等级高于当前物品等级或者二者等级之差大于限制数
book[j] = 1;//标记为不可访问
else
book[j] = 0;
}
minprice = dijstra();//调用dijstra函数计算出源点0到目标点1的最短路径即在原价格基础上优惠后的最低价格
if(minprice < mprice)
mprice = minprice;
}
cout<<mprice<<endl;//输出最低价格
}
return 0;
}