• POJ1062 昂贵的聘礼


    最短路径,Dijkstra算法。
    根据题意将每种物品看成每个顶点,优惠价格看成边,便构成一有向图,然后可以用Dijkstra求解。因为有等级限制,求一次Dijkstra是不行的。思想是枚举0~L的每一种限制i,除去不在区间[rand[1]-i,rand[i]+m-i](rand[1]为酋长的等级)的顶点,然后Dijkstra,取其中最小的。
    例如假设酋长等级为5,等级限制为2,那么需要枚举等级从3~5,4~6,5~7。从满足改等级范围的结点组成的子图中用Dijkstra来算出最短路径,最后求出最小值。
    构图时要注意的是,酉长的承诺不是最初的源点,它是一个目标点,也就是说点到点的指向方向是由无替代品的点逐渐指向到 酉长的承诺(1点),题意说明的是一个回溯的过程,因此可以定义一个最初的源点(0点),它到其他各点的权值就是每个物品的原价,而点A到点B的权值就是 物品B在有第A号替代品情况下的优惠价。

    还有知道了memset是以字节为单位的,所以初始化为最大值的时候,有时候不能用memset。

    #include <iostream>
    using namespace std;
    
    #define LEN 110
    const int INF (1<<30);
    
    int N;
    int M;
    int graph[LEN][LEN];
    int dist[LEN];
    int value[LEN];
    int level[LEN];
    bool visit[LEN];
    
    void init()     
    {     
        cin >> M >> N;
        for(int i = 0; i <= N; i++)  
            for(int j = 0; j <= N; j++)  
                if(i == j)  
                    graph[i][j] = 0;  
                else  
                    graph[i][j] = INF;  
        for(int i = 1;i <= N; i++)     
        {   
            int x;
            cin >> value[i] >> level[i] >> x;
        
            for(int j = 1; j <= x; j++)     
            {     
                int t, u;
                cin >> t >> u;  
                graph[t][i] = u;
            }     
        }     
    }     
    
    int dijkastra()
    {
        for (int i = 1; i <= N; i++)
        {
            dist[i] = value[i];
        }
        for (int i = 1; i <= N; i++)
        {
            int n = 0;
            int min = INF;
            for (int j = 1; j <= N; j++)
            {
                if (!visit[j] && dist[j] < min)
                {
                    n = j;
                    min = dist[j];
                }
            }
            if (n == 0) break;
            visit[n] = true;
            for (int j = 1; j <= N; j++)
            {
                if (!visit[j] && dist[n] + graph[n][j] < dist[j])
                {
                    dist[j] = dist[n] + graph[n][j];
                }
            }
        }
        return dist[1];
    }
    
    int main()
    {
        init();
        int result = INF;
        
        for (int i = 0; i <= M; i++)
        {
            int maxLevel = level[1] + i;
            for (int j = 1; j <= N; j++)
            {
                if (level[j] > maxLevel || maxLevel - level[j] > M)
                {
                    visit[j] = true;
                }
                else
                {
                    visit[j] = false;
                }
            }
            int min = dijkastra();
            if (min < result) result = min;
        }
        
        cout << result << endl;
        return 0;
    }
    

      

  • 相关阅读:
    5个有趣且不必要的 JavaScipt 技巧
    动态规划的原理?
    如何避免出现failfast?
    动态规划的原理?
    jsp文件导包
    程序突击
    monthly report
    weekly review: 细节决定一切
    weekly review
    祸从口入祸从口出
  • 原文地址:https://www.cnblogs.com/lautsie/p/3363588.html
Copyright © 2020-2023  润新知