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();
        }
    }
}
在写这段代码过程中,注意需要用一个数组保存队列,否则容易出现错误。
posted @ 2018-12-19 19:25  给我一个团队,干翻TX  阅读(2428)  评论(0编辑  收藏  举报