• POJ1062 昂贵的聘礼 【DFS】


    昂贵的聘礼
    Time Limit: 1000MS   Memory Limit: 10000K
    Total Submissions: 37475   Accepted: 10816

    Description

    年轻的探险家来到了一个印第安部落里。在那里他和酋长的女儿相爱了,于是便向酋长去求亲。酋长要他用10000个金币作为聘礼才答应把女儿嫁给他。探险家拿不出这么多金币。便请求酋长减少要求。酋长说:"嗯,假设你能够替我弄到大祭司的皮袄,我能够仅仅要8000金币。假设你能够弄来他的水晶球,那么仅仅要5000金币即可了。"探险家就跑到大祭司那里,向他要求皮袄或水晶球,大祭司要他用金币来换。或者替他弄来其它的东西。他能够减少价格。

    探险家于是又跑到其它地方,其它人也提出了类似的要求,或者直接用金币换,或者找到其它东西就能够减少价格。

    只是探险家不是必需用多样东西去换一样东西。由于不会得到更低的价格。探险家如今非常须要你的帮忙,让他用最少的金币娶到自己的心上人。另外他要告诉你的是,在这个部落里,等级观念十分森严。

    地位差距超过一定限制的两个人之间不会进行不论什么形式的直接接触。包含交易。他是一个外来人,所以能够不受这些限制。可是假设他和某个地位较低的人进行了交易,地位较高的的人不会再和他交易。他们觉得这样等于是间接接触,反过来也一样。因此你须要在考虑全部的情况以后给他提供一个最好的方案。 
    为了方便起见,我们把全部的物品从1開始进行编号,酋长的允诺也看作一个物品,而且编号总是1。

    每一个物品都有相应的价格P。主人的地位等级L,以及一系列的替代品Ti和该替代品所相应的"优惠"Vi。假设两人地位等级差距超过了M,就不能"间接交易"。你必须依据这些数据来计算出探险家最少须要多少金币才干娶到酋长的女儿。

     

    Input

    输入第一行是两个整数M,N(1 <= N <= 100),依次表示地位等级差距限制和物品的总数。接下来依照编号从小到大依次给出了N个物品的描写叙述。每一个物品的描写叙述开头是三个非负整数P、L、X(X < N),依次表示该物品的价格、主人的地位等级和替代品总数。

    接下来X行每行包含两个整数T和V,分别表示替代品的编号和"优惠价格"。

    Output

    输出最少须要的金币数。

    Sample Input

    1 4
    10000 3 2
    2 8000
    3 5000
    1000 2 1
    4 200
    3000 2 1
    4 200
    50 2 0
    

    Sample Output

    5250

    Source

    经典题。

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define maxn 110
    #define inf 0x3f3f3f3f
    
    struct Node {
        int price, level, down;
    } G[maxn];
    int head[maxn], m, n, id;
    struct Node2 {
        int v, val, next;
    } E[maxn * maxn];
    bool vis[maxn];
    int sta[maxn], id2; // sta防止间接等级越界
    
    void addEdge(int u, int v, int val) {
        E[id].v = v; E[id].next = head[u];
        E[id].val = val; head[u] = id++;
    }
    
    int min(int a, int b) {
        return a < b ? a : b;
    }
    
    int DFS(int u) {
        for(int i = 0; i < id2; ++i)
            if(abs(sta[i] - G[u].level) > m) 
                return inf;
        int v, ans = G[u].price;
        for(int i = head[u]; i != -1; i = E[i].next) {
            if(vis[v = E[i].v]) return inf;
            vis[v] = 1; sta[id2++] = G[u].level;
            ans = min(ans, E[i].val + DFS(v));
            vis[v] = 0; --id2;
        }
        return ans;
    }
    
    int solve() {
        memset(vis, 0, sizeof(bool) * (n + 1));
        int i, j, v, ans = G[1].price; vis[1] = 1;
        id2 = 0; sta[id2++] = G[1].level;
        for(i = head[1]; i != -1; i = E[i].next) {
            v = E[i].v; 
            ans = min(ans, E[i].val + DFS(v));
        }
        return ans;
    }
    
    int main() {
        int i, j, v, val;
        while(scanf("%d%d", &m, &n) == 2) {
            memset(head, -1, (n + 1) * sizeof(int));
            for(i = 1, id = 0; i <= n; ++i) {
                scanf("%d%d%d", &G[i].price, &G[i].level, &G[i].down);
                for(j = 0; j < G[i].down; ++j) {
                    scanf("%d%d", &v, &val);
                    addEdge(i, v, val);
                }
            }
            printf("%d
    ", solve());
        }
        return 0;
    }
    2015.2.7更新
    #include <stdio.h>
    #include <string.h>
    
    #define inf 0x3f3f3f3f
    #define maxn 110
    
    struct Node {
    	int P, L, X; // 价格、主人等级、替代品数
    } goods[maxn];
    struct Node2 {
    	int T, V; // 编号、价格优惠
    } substi[maxn][maxn];
    int M, N;
    bool vis[maxn];
    
    int min(int a, int b) { return a < b ?

    a : b; } int max(int a, int b) { return a > b ? a : b; } int solve(int numOfGoods, int minLevel, int maxLevel) { if (maxLevel - minLevel > M) return inf; int tempNumOfGoods, minL, maxL, i; int result = goods[numOfGoods].P; for (i = 1; i <= goods[numOfGoods].X; ++i) { tempNumOfGoods = substi[numOfGoods][i].T; if (vis[tempNumOfGoods]) continue; vis[tempNumOfGoods] = true; minL = min(minLevel, goods[tempNumOfGoods].L); maxL = max(maxLevel, goods[tempNumOfGoods].L); result = min(result, solve(tempNumOfGoods, minL, maxL) + substi[numOfGoods][i].V); vis[tempNumOfGoods] = false; } return result; } int main() { // freopen("data.in", "r", stdin); int i, j; while (scanf("%d%d", &M, &N) == 2) { memset(vis, 0, sizeof(vis)); for (i = 1; i <= N; ++i) { scanf("%d%d%d", &goods[i].P, &goods[i].L, &goods[i].X); for (j = 1; j <= goods[i].X; ++j) scanf("%d%d", &substi[i][j].T, &substi[i][j].V); } printf("%d ", solve(1, goods[1].L, goods[1].L)); } return 0; }


    2015.04.13更新

    #include <stdio.h>
    #include <string.h>
    
    const int maxn = 110;
    const int inf = 0x3f3f3f3f;
    int head[maxn], id;
    struct Node {
        int v, w, next;
    } E[maxn*maxn];
    struct Node2 {
        int price, level;
    } Per[maxn];
    int N, M, dp[maxn];   // N articles
    
    int min(int a, int b) { return a < b ? a : b; }
    int max(int a, int b) { return a > b ? a : b; }
    
    void addEdge(int u, int v, int w)
    {
        E[id].v = v;
        E[id].w = w;
        E[id].next = head[u];
        head[u] = id++;
    }
    
    void getMap()
    {
        int i, j, P, L, K, w, v;
    
        memset(head, -1, sizeof(head));
        memset(dp, 0, sizeof(dp));
    
        for (id = 0, i = 1; i <= N; ++i) {
            scanf("%d%d%d", &P, &L, &K);
            Per[i].price = P;
            Per[i].level = L;
            while (K--) {
                scanf("%d%d", &v, &w);
                addEdge(i, v, w);
            }
        }
    }
    
    int findMinCost(int k, int maxLevel, int minLevel)
    {
        maxLevel = max(maxLevel, Per[k].level);
        minLevel = min(minLevel, Per[k].level);
        if (maxLevel - minLevel > M)
            return inf;
        else if (dp[k]) return dp[k];
    
        int ret = Per[k].price;
        int i, v;
    
        dp[k] = Per[k].price;
        for (i = head[k]; i != -1; i = E[i].next) {
            v = E[i].v;
            dp[k] = min(dp[k], findMinCost(v, maxLevel, minLevel) + E[i].w);
        }
    
        return dp[k];
    }
    
    int solve()
    {
        return findMinCost(1, Per[1].level, Per[1].level);
    }
    
    int main()
    {
        while (~scanf("%d%d", &M, &N)) {
            getMap();
            printf("%d
    ", solve());
        }
        return 0;
    }



     

  • 相关阅读:
    高效 告别996,开启java高效编程之门 3-16收集器与预定义收集器概述
    高效 告别996,开启java高效编程之门 3-15实战:流的构建四种形式
    高效 告别996,开启java高效编程之门 3-14常用操作总结与流构建描述
    高效 告别996,开启java高效编程之门 3-13实战:常用终端操作之最大/最小/计数
    高效 告别996,开启java高效编程之门 3-12实战:常用终端操作之查找
    高效 告别996,开启java高效编程之门 3-11实战:常用终端操作之匹配
    cube中的判断类型
    正则表达式解析基本json
    敏捷开发入门教程-----摘抄
    单页面路由样例
  • 原文地址:https://www.cnblogs.com/yxwkf/p/5184121.html
Copyright © 2020-2023  润新知