zoukankan      html  css  js  c++  java
  • POJ 1062 昂贵的聘礼

    题目链接:http://poj.org/problem?id=1062

    题目大意:这道题实际上就是图的最短路径问题

    解题思路:建图, 结点为每件物品,把探险者也看成一个入度为零的节点,是n + 1结点之一,探险者到其他物品的直接连线的权值为物品的原始价格,其他 i -> j的边的权值为探险者获得i后换j

    的优惠价格。应该注意的是,由于等级限制,如果你和level[1] - k级别的人交易过,那么你最多只能和level[1] - k + m进行交易,因此我们要对这m个等级范围进行枚举,每次枚举只考虑该等

    级范围内的点,并求出n + 1点到1点的最小值(最短路,dijkstra),再记录多次枚举得到的最小值,最后的最小值即为所求答案。代码中还有详细的解释

    注意点:

    1.代码中涉及到了不少的数组,所以对于某些有特定含义的数组一定要进行初始化,以免在后面的数值比较时出错

    2.在设置一个很大的数字时要小心,最好是不要设置为最大整型数Integer.MAX_VALUE,因为一旦它参与运算就会出现不可预料的错误,如果它只是进行数值比较的话,那么是可以的

    3.这道题目解法很多,建图可以用邻接矩阵也可以用邻接表,求最短路径可以用Dijkstra 也可以用其他的方法(例如:spfa)

    我AC的Java代码:

    Memory: 5072K
    Time: 1641MS

    /**
     * @Author:胡家威  
     * @CreateTime:2011-7-16 上午09:09:57
     * @Description:AC
     */
    
    package ACM.POJ;
    
    import java.util.Scanner;
    
    public class POJ1062 {
    
        public static int[][] map = new int[101][101];// matrix 表示图的邻接矩阵[有向图]
        public static int[] level = new int[101];// level
        public static int[] dist = new int[101];// distance 从0到该点的权值
        public static int[] mark = new int[101];// mark 标记是否可以和他进行交易
        public static int m;// level distance
        public static int n;// goods number
        public static int ans;// result
        //public static int INF = Integer.MAX_VALUE;//错误原因
        public static int INF = 10000000;
    
        public static void main(String[] args) {
            Scanner sin = new Scanner(System.in);
            m = sin.nextInt();// 等级限制和物品数目
            n = sin.nextInt();
            int i, j, k, t;
            for (i = 0; i <= n; i++) {
                for (j = 0; j <= n; j++) {
                    map[i][j] = INF;// 初始化邻接矩阵
                }
            }
            for (i = 1; i <= n; i++) {
                map[0][i] = sin.nextInt();// 价格和等级
                level[i] = sin.nextInt();
                t = sin.nextInt();
                for (j = 1; j <= t; j++) {// 替代品
                    k = sin.nextInt();
                    map[k][i] = sin.nextInt();// 建立有权边
                }
            }
            dijkstra();
        }
    
        public static void dijkstra() {
            int i, j, k, start, min;
            ans=INF;
            for (k = 0; k <= m; k++) {// 枚举等级差
                for (i = 1; i <= n; i++) {
                    if (level[i] - level[1] <= k && level[1] - level[i] <= m - k) {
                        mark[i] = 1;// 表示可以进行交易,即可以访问的点
                        dist[i] = map[0][i];
                    } else {
                        mark[i] = 0;
                        dist[i] = INF;
                    }
                }
                for (i = 1; i <= n; i++) {
                    start = 1;//设置1为起点,如果没有可以的中间点,那么1也就是终点了
                    min = INF;//这两个值每次循环时都要重置一下
                    for (j = 1; j <= n; j++) {//得到距离最短的点
                        if (mark[j] == 1 && dist[j] < min) {//可以访问的点中距离最近的
                            start = j;
                            min = dist[j];
                        }
                    }
                    mark[start] = 0;//将刚刚得到的距离最短的点标记为不能访问了
                    for (j = 1; j <= n; j++) {//由于新的点的加入,要修改距离值[从0开始到该点的最短距离值]
                        if (mark[j] == 1 && dist[j] > dist[start] + map[start][j]) {//修改其他的可以访问的点的距离值
                            dist[j] = dist[start] + map[start][j];
                        }
                    }
                }
                if(ans>dist[1])
                    ans=dist[1];
            }
            System.out.println(ans);
        }
    
    }
  • 相关阅读:
    第二节:简单工厂模式(静态工厂模式)
    第一节:不使用设计模式的传统方式
    第三章:设计模式概述
    第二节:类与类之间的关系
    高斯混合模型(GMM)
    随机森林
    LDA主题模型
    Adaboost算法
    线性代数
    k-means聚类
  • 原文地址:https://www.cnblogs.com/yinger/p/2109040.html
Copyright © 2011-2022 走看看