1. 程式人生 > >CCF之最優配餐(java)

CCF之最優配餐(java)

試題編號: 201409-4
試題名稱: 最優配餐
時間限制: 1.0s
記憶體限制: 256.0MB
問題描述: 問題描述   棟棟最近開了一家餐飲連鎖店,提供外賣服務。隨著連鎖店越來越多,怎麼合理的給客戶送餐成為了一個急需解決的問題。
  棟棟的連鎖店所在的區域可以看成是一個n×n的方格圖(如下圖所示),方格的格點上的位置上可能包含棟棟的分店(綠色標註)或者客戶(藍色標註),有一些格點是不能經過的(紅色標註)。
  方格圖中的線表示可以行走的道路,相鄰兩個格點的距離為1。棟棟要送餐必須走可以行走的道路,而且不能經過紅色標註的點。


  送餐的主要成本體現在路上所花的時間,每一份餐每走一個單位的距離需要花費1塊錢。每個客戶的需求都可以由棟棟的任意分店配送,每個分店沒有配送總量的限制。
  現在你得到了棟棟的客戶的需求,請問在最優的送餐方式下,送這些餐需要花費多大的成本。 輸入格式   輸入的第一行包含四個整數n, m, k, d,分別表示方格圖的大小、棟棟的分店數量、客戶的數量,以及不能經過的點的數量。
  接下來m行,每行兩個整數xi, yi,表示棟棟的一個分店在方格圖中的橫座標和縱座標。
  接下來k行,每行三個整數xi, yi, ci,分別表示每個客戶在方格圖中的橫座標、縱座標和訂餐的量。(注意,可能有多個客戶在方格圖中的同一個位置)
  接下來d行,每行兩個整數,分別表示每個不能經過的點的橫座標和縱座標。 輸出格式   輸出一個整數,表示最優送餐方式下所需要花費的成本。 樣例輸入 10 2 3 3
1 1
8 8
1 5 1
2 3 3
6 7 2
1 2
2 2
6 8 樣例輸出 29 評測用例規模與約定   前30%的評測用例滿足:1<=n <=20。
  前60%的評測用例滿足:1<=n<=100。
  所有評測用例都滿足:1<=n<=1000,1<=m, k, d<=n^2。可能有多個客戶在同一個格點上。每個客戶的訂餐量不超過1000,每個客戶所需要的餐都能被送到。

解題程式碼(java):

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class Main {
	static class Vertex implements Cloneable {
		public int x;
		public int y;
		public int step;

		public Vertex(int x, int y, int step) {
			this.x = x;
			this.y = y;
			this.step = step;

		}

		public Vertex() {

		}
	}

	public static void main(String[] args) {

		long[][] map = new long[1001][1001];
		Queue<Vertex> q = new LinkedList<Vertex>();
		boolean[][] vis = new boolean[1001][1001];
		int[][] move = { { 0, 1 }, { 0, -1 }, { 1, 0 }, { -1, 0 } };

		Scanner in = new Scanner(System.in);
		long size = in.nextLong();
		long m = in.nextLong();
		long k = in.nextLong();
		long d = in.nextLong();
		for (int i = 0; i < m; i++) {
			int x = in.nextInt();
			int y = in.nextInt();
			int step = 0;
			q.add(new Vertex(x, y, step));
		}
		for (int i = 0; i < k; i++) {
			int x = in.nextInt();
			int y = in.nextInt();
			int z = in.nextInt();
			map[x][y] = z;
		}

		for (int i = 0; i < d; i++) {
			int x = in.nextInt();
			int y = in.nextInt();
			vis[x][y] = true;

		}
		in.close();
		long cnt = 0;
		long ans = 0;

		while (!q.isEmpty()) {
			Vertex u = q.remove();

			for (int i = 0; i < 4; i++) {
				Vertex tem = new Vertex();

				tem.x = u.x;
				tem.y = u.y;
				tem.step = u.step;
				tem.x += move[i][0];
				tem.y += move[i][1];
				tem.step++;
				if (tem.x > 0 && tem.y <= size && tem.y > 0 && tem.x <= size && !vis[tem.x][tem.y]) {
					vis[tem.x][tem.y] = true;
					if (map[tem.x][tem.y] != 0) {
						ans += map[tem.x][tem.y] * tem.step;
						++cnt;
						if (cnt == k)
							break;
					}
					q.add(tem);
				}
			}
		}

		System.out.println(ans);

	}

}

得分80 ,歡迎指正