//5056K 1750MS Java
import java.util.Scanner;
import java.util.LinkedList;
public class Main {
private static int sDealerNum;
private static int sMaxPosDiff;
public int dealPrice;
// private class Dealer {
// public int orginalPrice;
// public int pos;
// }
private int [] dealerOrginalPrice;
private int [] dealersPos;
private int[][] dealInfo;
// private Dealer[] dealers;
private int[] dealBegin;
private int dealBeginNum;
public int dealerNum;
public void addDealer(int pos, int orginalPrice) {
dealerOrginalPrice[dealerNum] = orginalPrice;
dealersPos[dealerNum++] = pos;
// dealers[dealerNum++].dealNum = dealNum;
}
public void addDealInfo(int dealerId, int requireDealerId, int dealPrice) {
dealInfo[dealerId][requireDealerId] = dealPrice;
}
private static final int INF = 99999;
private int[] distanceInfo;
private boolean[] dealerProcessedMap;
private void prepareForDJ() {
for (int i = 0; i < dealerNum; i++) {
distanceInfo[i] = INF;
dealerProcessedMap[i] = false;
}
}
private int dfs(int curNodeId, int maxPos, int minPos) {
// System.out.println(curNodeId + " " + maxPos + " " + minPos);
dealerProcessedMap[curNodeId] = true;
int minCost = dealerOrginalPrice[curNodeId];
for (int i = 0; i < dealerNum; i++) {
if (dealInfo[curNodeId][i] >= 0 && !dealerProcessedMap[i]) { // can deal
int newPos = dealersPos[i];
int newMaxPos = newPos > maxPos ? newPos : maxPos;
int newMinPos = newPos < minPos ? newPos : minPos;
if (newMaxPos - newMinPos <= sMaxPosDiff) { // these 2 Pos can deal.
dealerProcessedMap[i] = true;
int res = dealInfo[curNodeId][i] + dfs(i, newMaxPos, newMinPos);
minCost = minCost < res ? minCost : res;
dealerProcessedMap[i] = false;
}
}
}
return minCost;
}
private int beginGetShortest(int begin) {
distanceInfo[begin] = dealerOrginalPrice[begin];
dealerProcessedMap[begin] = true;
int minCost = dfs(begin, dealersPos[begin], dealersPos[begin]);
return minCost;
}
public void process() {
prepareForDJ();
int cost = beginGetShortest(0);
System.out.println(cost);
}
public void solve() {
process();
resetEnv();
}
public void resetEnv() {
for (int i = 0; i < 100; i++) {
dealerProcessedMap[i] = false;
for (int j = 0; j < 100; j++) {
dealInfo[i][j] = -1;
}
}
dealerNum = 0;
}
public Main() {
dealerOrginalPrice = new int[100];
dealersPos = new int[100];
dealInfo = new int[100][100];
dealerNum = 0;
distanceInfo = new int[100];
dealerProcessedMap = new boolean[100];
// dealers = new Dealer[100];
// for (int i = 0; i < 100; i++) {
// dealers[i] = new Dealer();
// }
resetEnv();
}
public static void main(String args[]) {
Main solver = new Main();
Scanner input = new Scanner(System.in);
while(input.hasNext()) {
sMaxPosDiff = input.nextInt();
sDealerNum = input.nextInt();
for (int i = 0; i < sDealerNum; i++) {
int orginalPrice = input.nextInt();
int pos = input.nextInt();
int dealNum = input.nextInt();
solver.addDealer(pos, orginalPrice);
for (int j = 0; j < dealNum; j++) {
int requireDealerId = input.nextInt();
int dealPrice = input.nextInt();
solver.addDealInfo(i, requireDealerId-1, dealPrice);
}
}
solver.solve();
}
}
}
5056K 1750MS Java
比较扯的一道题,在最短路的分类中找到的该题,一开始想用DJ算法来做,搞到后面才发现,因为引入了等级差距大不能交易的因素,DJ这种基于BFS的思路是不行的,
(虽然discuss里有人说自己用BFS做出来了,不过应该是凑巧碰对了,用BFS是有一定概率正确的,条件是正好第一次走过了正确的路)。因此直接转投DFS,
这里遇到一个问题,因为在DFS的时候遍历忘了加 node是否经过的flagcheck,导致出现了无限递归,关键是如果是java的话,在POJ上无限调用的错误不会是RE,
而是MLE(因为函数栈帧把内存吃完了),一开始还以为真是内存占多了,拼命的减,结果还是MLE,后来转成C代码才发现是无限调用..... 坑呀。还是自己不细心呀,
关键错误的code跑几个case都没问题.... 囧。
思路其实很简单,就是纯粹的DFS,从酋长开始(一开始搞成以不会再优惠的交易者开始,其实不对,因为有时候不一定从不会优惠的交易者开始就一定最少,比如:
4个人,酋长(第一个人1)认同 2 或 3的物品, 4不会优惠,2的部落等级更高(但2在输入认同4的物品),这种情况是可能的,因此如果和2交易的话,就不能再和 3 ,4 交易,而另一条购买链是1->3->4
跟 1->2比起来, 如果酋长对2的物品优惠足够多的,最优解是从2而不是从4开始,所以最好从酋长开始,当然,真从其他人开始,也是可以的,不过要从不会再和别人交易的人开始,这样有时候会DFS几次,有些浪费效率),不过要加一些额外的条件判断(就是交易者的部落等级差别),每次DFS,除了会传进去此轮DFS开始的nodeId(就是交易者)外,还会传进去这条交易链(也就是函数调用链)中交易者们的最高部落等级和最低部落等级,新一轮交易要保证新交易者的部落等级,结合之前的最高和最低部落等级,
不会出现超过了部落等级限制的情况,如果出现这种情况,那么此次交易就在该交易者这里结束(花费总额就是该交易者的物品的全额 将上 之前交易者的优惠价),然后返回,就是这一个购买链的最少价钱, 如果可以继续,那么继续DFS,不过要刷新最大等级和最小等级(很关键)。从酋长开始遍历所有可交易的对象,每个对象对应一个购买链,最后找到花费最小的购买链的价钱就是所求。
这道题算是一道DFS好题,转化和变种难度都恰到好处.
如果没有规定部落等级限制,BFS的DJ算法完全OK,最开始还有想法,比较每个交易者的等级,再结合交易信息,来真正确定一张图,但是后来发现不行,
因此购买路径中,等级区间不是由一个点决定的,而是取决与购买路径是怎么走的,完全是动态变化的,因此BFS是不行的.