poj-1062

本文介绍了一种使用深度优先搜索(DFS)解决特定部落交易问题的方法。问题涉及到一系列的交易限制,包括不同部落间的交易等级差异。通过从部落酋长开始进行DFS遍历,结合考虑部落等级差异限制,寻找成本最低的交易路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//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是不行的.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值