• java,优先队列的用法


    像C++语言一样,java中,也有包装好的优先队列类PriorityQueue。

    用法如下(模板代码):

    工作安排问题:

       问题描述:设有n件工作分配给n个人,将工作i分配给第j个人所需的费用为cij。试设计一个算法,为每个人都分配一件不同的工作,并使得总费用达到最小。

       输入:第1行有1个正整数n(1≤n≤20),接下来的n行,每行n个数,表示工作费用。

       输出:计算的最小总费用

       样例输入:                  样例输出:

       3                            9

       10  2  3

       2   3   4

       3   4   5

    使用优先级分支限界的方法,很容易解决这道题目,但是在写代码的过程中,是很容易出现错误,因此需要注意!!!。

    package com.KongLong;
    
    import java.util.Comparator;
    import java.util.PriorityQueue;
    import java.util.Queue;
    import java.util.Scanner;
    
    class Money
    {
        int CurrentMoney;//当前费用;
        int PossibleMoney;//当前结点可能最小的费用
        int locat;//当前的行坐标
        boolean vis[] = new boolean[25];
    }
    class Cmp implements Comparator<Money>//优先级排序
    {
        public int compare(Money o1, Money o2) 
        {
            if(o1.PossibleMoney > o2.PossibleMoney)
            {
                return 1;
            }
            else if(o1.PossibleMoney == o2.PossibleMoney)
            {
                return 0;
            }
            else
            {
                return -1;
            }
        }
    }
    public class Main
    {
        static int N;
        static final int MAX = 25;
        static int money[][] = new int[MAX][MAX];//邻接矩阵
        static Money M[] = new Money[MAX];//在队列中使用
        static int cnt = 0;
        static Queue<Money> que = new PriorityQueue<Money>(MAX,new Cmp());//优先队列
        static int result;
        public static void main(String []args)
        {
            init();
            Scanner cin = new Scanner(System.in);
            N = cin.nextInt(); 
            cnt = 0;
            result = 99999999;
            for(int i = 0; i < N; i++)
            {
                for(int j = 0; j < N; j++)
                {
                    money[i][j] = cin.nextInt();
                }
            }
            for(int i = 0; i < N; i++)
            {
                M[cnt].CurrentMoney = money[0][i];
                M[cnt].locat = 0;
                M[cnt].vis[i] = true;
                M[cnt].PossibleMoney = M[cnt].CurrentMoney+Bound(1);
                //System.out.println(M[cnt].PossibleMoney);
                que.add(M[cnt]);
                cnt++;
            }
            while(!que.isEmpty())//队列为空判断
            {
                Money a = new Money();
                a = que.poll();
                //System.out.println(a.CurrentMoney + ">>>>>>>  " + a.PossibleMoney + ">>> " + a.locat);
                if(a.locat == N-1 && a.CurrentMoney < result)//界限
                {
                    result = a.CurrentMoney;
                    //System.out.println("000");
                    continue;
                }
                else if(a.locat == N-1)//界限
                {
                    continue;
                }
                else if(a.PossibleMoney > result)//剪枝
                {
                    break;
                }
                for(int i = 0; i < N; i++)
                {
                    if(a.vis[i] == true)
                    {
                        continue;
                    }
                    M[cnt].CurrentMoney = a.CurrentMoney+money[a.locat+1][i];
                    M[cnt].vis[i] = true;
                    for(int j = 0; j < N; j++)
                    {
                        if(a.vis[j] == true)
                        {
                            M[cnt].vis[j] = true;
                        }
                        //System.out.println(M[cnt].vis[j]);
                    }
                    M[cnt].locat = a.locat+1;
                    M[cnt].PossibleMoney = M[cnt].CurrentMoney+Bound(a.locat+2);
                    //System.out.println(M[cnt].CurrentMoney + " >>>>>>>>>>> " + M[cnt].PossibleMoney + " yyyyy ");
                    //M[cnt].vis[i] = true;
                    que.add(M[cnt]);
                    cnt++;
                }
            }
            System.out.println(result);
        }
        static int Bound(int j)//当前结点的最小费用
        {
            int sum = 0;
            for(int i = j; i < N; i++)
            {
                int Min = 99999999;
                for(int k = 0; k < N; k++)
                {
                    if(M[cnt].vis[k] == true)
                    {
                        //System.out.println(k + "k");
                        continue;
                    }
                    Min = Math.min(Min, money[i][k]);
                }
                sum += Min;
            }
            //System.out.println(j + "///// " + sum);
            return sum;
        }
        static void init()
        {
            for(int i = 0; i < MAX; i++)
            {
                M[i] = new Money();
            }
        }
    }
    在写这段代码过程中,注意需要用一个数组保存队列,否则容易出现错误。
  • 相关阅读:
    js语言基础练习(二)---------------函数的基础知识
    js语言基础练习
    js基本语法总结(一)
    HTML基础知识总结
    参考资料
    css基础知识的复习总结(三)
    css基础知识的复习总结(二)
    css基础知识的复习总结
    旋转数组
    CSS 之 position
  • 原文地址:https://www.cnblogs.com/674001396long/p/10145364.html
Copyright © 2020-2023  润新知