• (最短路 dijkstra)昂贵的聘礼 -- poj -- 1062


    链接:

    http://poj.org/problem?id=1062

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

    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
    dijkstra
    #include <iostream>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <stack>
    using namespace std;
    const int INF = (1<<30)-1;
    #define maxn 205
    #define MAXN 150005
    #define min(a,b) (a<b?a:b)
    #define max(a,b) (a>b?a:b)
    
    int M, N;
    int dist[maxn], G[maxn][maxn], lv[maxn];
    bool vis[maxn];
    
    int Dij()
    {
        int i, j, k, ans = G[0][1];
    
        for(k=lv[1]-M; k<=lv[1]; k++)
        {
            memset(vis, false, sizeof(vis));
            for(i=1; i<=N; i++)
            {
                dist[i] = G[0][i];
    
                if(lv[i]<k || lv[i]>k+M)
                    vis[i] = true;
            }
    
            for(i=1; i<=N; i++)
            {
                int index, Min=INF;
                for(j=1; j<=N; j++)
                {
                    if(!vis[j] && dist[j]<Min)
                    {
                        Min = dist[j];
                        index = j;
                    }
                }
                vis[index] = true;
    
                for(j=1; j<=N; j++)
                {
                    if(!vis[j] && dist[j] > G[index][j] + dist[index])
                        dist[j] = G[index][j] + dist[index];
                }
            }
    
            ans = min(ans, dist[1]);
        }
        return ans;
    }
    
    int main()
    {
        while(scanf("%d%d", &M, &N)!=EOF)
        {
            int i, j, X, T, V;
    
            for(i=0; i<=N; i++)
            for(j=0; j<=i; j++)
            G[i][j] = G[j][i] = INF;
            G[i][j] = 0;
    
            for(i=1; i<=N; i++)
            {
                scanf("%d%d%d", &G[0][i], &lv[i], &X);
                while(X--)
                {
                    scanf("%d%d", &T, &V);
                    G[T][i] = V;
                }
            }
    
            printf("%d
    ", Dij());
        }
        return 0;
    }
    #include<stdio.h>
    #include<vector>
    #include<stack>
    #include<algorithm>
    #include<string.h>
    #include<math.h>
    using namespace std;
    
    const int maxn = 10005;
    const int maxm = 105;
    const int oo = 0xfffffff;
    
    struct node
    {
        int u, v, price, next;
    }e[maxn];
    int head[maxm], lv[maxm], p[maxm];
    bool use[maxm];
    
    void Add(int u, int v, int c, int k)
    {
        e[k].u = u;
        e[k].v = v;
        e[k].price = c;
        e[k].next = head[u];
        head[u] = k;
    }
    
    int Dfs(int MaxLv, int MinLv, int k, int M)
    {
        int MinP = oo;
    
        for(int i=head[k]; i!=0; i=e[i].next)
        {
            int v = e[i].v;
            int c = e[i].price;
    
            if(lv[v] >= MinLv && lv[v] <= MaxLv && use[v] == false)
            {
                use[v] = true;
    
                int L = min(MaxLv, lv[v]+M);
                int R = max(MinLv, lv[v]-M);
    
                MinP = min(MinP, Dfs(L, R, v, M)+c);
    
                use[v] = false;
            }
        }
    
        return min(p[k], MinP);
    }
    
    int main()
    {
        int N, M;
    
        while(scanf("%d%d", &M, &N) != EOF)
        {
            int i, k=1, v, price, T;
    
            memset(head, 0, sizeof(head));
    
            for(i=1; i<=N; i++)
            {
                scanf("%d%d%d", &p[i], &lv[i], &T);
    
                while(T--)
                {
                    scanf("%d%d", &v, &price);
                    Add(i, v, price, k++);
                }
            }
    
            use[1] = true;
            int ans = Dfs(lv[1]+M, lv[1]-M, 1, M);
    
            printf("%d
    ", ans);
        }
    
        return 0;
    }
    勿忘初心
  • 相关阅读:
    css样式表
    js正则表达式
    jQuery工具函数
    jquery tmpl 详解
    JS产生随机数的几个用法!
    IE浏览器中用Firebug调试网站的方法
    CSS clip:rect矩形剪裁功能及一些应用介绍
    如何修改vs2010中html的默认模板
    sublime text 3 注册机
    SQL语句报com.alibaba.druid.sql.parser.ParserException: TODO IDENTIFIER cross
  • 原文地址:https://www.cnblogs.com/YY56/p/4812478.html
Copyright © 2020-2023  润新知