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();
        }
    }
}
在寫這段代碼過程中,注意需要用一個數組保存隊列,否則容易出現錯誤。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM