题目:输入第一行是两个整数M--等级差距,N(1 <=N <= 100)物品的总数。接下来按照编号从小到大依次给出了N个物品的描述。每个物品的描述开头是三个非负整数P--价格、L--等级、X替代品总数(X< N)。接下来X行每行包括两个整数T---编号,V---价格。
分析:等级差距不能大于M,N个物品都要有,或者用其替代物替代,替代物有两个不是说必须用两个替代,而是只要替代中的一个就行;要求找出价格最少的情况;及,如果替代物比原物合适,就用替代物替代,找到最小值;所以用dijkstra最小路径算法---地杰卡斯特最短路径;
最短路径算法的原理:Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低。
用说的不太清楚,我搞过来一幅图:
初始时,S中仅含有源。设u是G的某一个顶点,把从源到u且中间只经过S中顶点的路称为从源到u的特殊路径,并用数组dist记录当前每个顶点所对应的最短特殊路径长度。Dijkstra算法每次从V-S中取出具有最短特殊路长度的顶点u,将u添加到S中,同时对数组dist作必要的修改。一旦S包含了所有V中顶点,dist就记录了从源到所有其它顶点之间的最短路径长度。
对照找到的这道题的代码进行分析:
private static voiddijkstra() {
for (int i = 1; i <= n; i++) {//对dis数组进行初始化,其中e[0][i]存放的是原物件的价格,没用替代物;
dis[i]= e[0][i];
}
for(int i = 1; i <= n; i++) {
intmin = Integer.MAX_VALUE;
intk = 0;
for(int j = 1; j <= n; j++) {// 求不用原物件时的最小值
if(used[j] == 0 && dis[j] < min) {
k =j;
min= dis[j];
}
}
if(k == 0)
break;
used[k]= 1;
for(int j = 1; j <= n; j++) {
//看替代品中有没有比上面的值更小的值,有的话用min更新其他节点,让所有节点都呈现一个最小值;if (used[j] == 0 &&e[k][j] > 0 && e[k][j] + min < dis[j]) {
dis[j]= e[k][j] + min;
}
}
}
}
其实还是有地方没搞明白,但是作为图论的第一道题,先这样,有机会总结的时候回来再搞明白!