201409-4 最优配餐

试题编号: 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,每个客户所需要的餐都能被送到。

采用BFS,多点同时出发,最快达到的为最短。

#include <map>  
#include <cmath>  
#include <queue>  
#include <cstdio>  
#include <string>  
#include <cstring>  
#include <iostream>  
#include <algorithm> 
#include <sstream> 
#include <time.h> 
#include <vector>
#include <list>
using namespace std;

//201409-4 最优配餐(60)
struct Tran {
	char flag;
	int lenth;		//flag代表状态0:搜索完,1:搜索部分,2:未搜索
/*	int mum_x, mum_y;	*/	
};
struct Pos {
	int x, y, val;		
	Pos(int _x, int _y) : x(_x), y(_y) {}
	Pos() {}
};

Pos dir[4] = { { 0, 1 },{ 0, -1 },{ 1, 0 },{ -1, 0 } };

int main()
{
	int i, j, t;
	int N, M, K, D;

	cin >> N >> M >> K >> D;	//方格图的大小、栋栋的分店数量、客户的数量,不能经过的点的数量
	vector<vector<Tran> >xlim(N+1, vector<Tran>(N+1, { 0, -1 }));
	vector<Pos>Fendian(M + 1), Kehu(K + 1);
	//vector<vector<int> >Data(M, vector<int>(K));
	//int Data[1001][1001];
	vector<int> Out(K);

	for (i = 1; i <= N; i++)
	{
		for (j = 1; j <= N; j++)
		{
			xlim[i][j].flag = 2;
		}
	}
	for (i = 1; i <= M; i++)
	{
		cin >> Fendian[i].x >> Fendian[i].y;
		//xlim[Fendian[i].x][Fendian[i].y].flag = 0;
	}
	for (i = 1; i <= K; i++)
	{
		cin >> Kehu[i].x >> Kehu[i].y >> Kehu[i].val;
		//xlim[Kehu[i].x][Kehu[i].y].flag = 0;
	}
	for (i = 1; i <= D; i++)			
	{
		int x, y;
		cin >> x >> y;
		xlim[x][y].flag = 0;
	}
	//cout << "1" << endl;
	int judge = 0;				//判断已找到所有客户
	for (i = 1; i <= K; i++)
	//for (i = 1; i <= M; i++)
	{
		queue<Pos>store;					//先进先出队列
		vector<vector<Tran> > b(xlim);		//复制一份坐标图

		b[Kehu[i].x][Kehu[i].y].flag = 1;
		b[Kehu[i].x][Kehu[i].y].lenth = 0 ;
		store.push(Kehu[i]);
		//b[Fendian[i].x][Fendian[i].y].flag = 1;
		//b[Fendian[i].x][Fendian[i].y].lenth = 0;
		//store.push(Fendian[i]);

		//cout << "2" << endl;
		int c1= 0, c2=0;
		while (!store.empty())
		{
			Pos p = store.front();				//根节点
			for (j = 0; j < 4; j++)
			{
				Pos now (p.x + dir[j].x, p.y + dir[j].y);		//分支
				// 下面若坐标不在范围内会出现超限错误,放后面就不会了
				if (now.x > 0 && now.y > 0 && now.x <= N && now.y <= N && b[now.x][now.y].flag == 2)
				{
					b[now.x][now.y].flag = 1;
					b[now.x][now.y].lenth = b[p.x][p.y].lenth + 1;
					//b[now.x][now.y].mum_x = p.x;			//表示母节点位置
					//b[now.x][now.y].mum_y = p.y;
					store.push(now);
					///*当所有客户都寻到后退出*/
					//for (t = 1; t <= K; t++)
					//{
					//	if (now.x == Kehu[t].x && now.y == Kehu[t].y)
					//	{
					//		judge++;
					//		//cout << judge << " "<< p.x <<" "<< p.y<< endl;
					//		if (judge == K)
					//		{
					//			judge = 0;
					//			goto jump;
					//		}
					//	}
					//}
					///*当有分店被找到*/
					for (t = 1; t <= M; t++)
					{
						if (now.x == Fendian[t].x && now.y == Fendian[t].y)
						{
							Out[i - 1] = b[now.x][now.y].lenth;
							/*cout <<i<< " "<< now.x <<" "<< now.y<< endl;*/
							goto jump;
						}
					}
				}
			}
			b[p.x][p.y].flag = 0;
			store.pop();
		}
		//cout << "3" << endl;
	jump:;
		//for (j = 1; j <= K; j++)
		//{
		//	Data[i-1][j-1]= b[Kehu[j].x][Kehu[j].y].lenth;
		//}

	}
/*	cout << "4" << endl;	*/		
	long long num = 0;
	for (j = 1; j <= K; j++)
	{
		//Out[j - 1] = Data[0][j - 1];
		//for (t = 1; t < M; t++)
		//{
		//	if (Data[t][j - 1] < Out[j - 1])
		//		Out[j - 1] = Data[t][j - 1];
		//}
		num += Out[j - 1] * Kehu[j].val;		//最短路径*客户订餐数
	}
	cout << num;
	cin >> N;
	return 0;
}

#include <map>  
#include <cmath>  
#include <queue>  
#include <cstdio>  
#include <string>  
#include <cstring>  
#include <iostream>  
#include <algorithm> 
#include <sstream> 
#include <time.h> 
#include <vector>
#include <list>
using namespace std;

//201409-4 最优配餐(100)
struct Tran {
	char flag;
	int lenth;		//flag代表状态0:搜索完,1:搜索部分,2:未搜索
					/*	int mum_x, mum_y;	*/
};
struct Pos {
	int x, y, val;
	Pos(int _x, int _y) : x(_x), y(_y) {}
	Pos() {}
};

Pos dir[4] = { { 0, 1 },{ 0, -1 },{ 1, 0 },{ -1, 0 } };

int main()
{
	int i, j, t;
	int N, M, K, D;

	cin >> N >> M >> K >> D;	//方格图的大小、栋栋的分店数量、客户的数量,不能经过的点的数量
	vector<vector<Tran> >xlim(N + 1, vector<Tran>(N + 1, { 0, -1 }));
	vector<Pos>Fendian(M + 1), Kehu(K + 1);

	for (i = 1; i <= N; i++)
	{
		for (j = 1; j <= N; j++)
		{
			xlim[i][j].flag = 2;
		}
	}
	for (i = 1; i <= M; i++)
	{
		cin >> Fendian[i].x >> Fendian[i].y;
	}
	for (i = 1; i <= K; i++)
	{
		cin >> Kehu[i].x >> Kehu[i].y >> Kehu[i].val;
	}
	for (i = 1; i <= D; i++)
	{
		int x, y;
		cin >> x >> y;
		xlim[x][y].flag = 0;
	}
	//cout << "1" << endl;
	int judge = 0;				//判断已找到所有客户
	queue<Pos>store;					//先进先出队列
	vector<vector<Tran> > b(xlim);		//复制一份坐标图

	for (i = 1; i <= M; i++)
	{
		b[Fendian[i].x][Fendian[i].y].flag = 1;
		b[Fendian[i].x][Fendian[i].y].lenth = 0;
		store.push(Fendian[i]);
	}
	//cout << "2" << endl;
	int c1 = 0, c2 = 0;
	while (!store.empty())
	{
		Pos p = store.front();				//根节点
		for (j = 0; j < 4; j++)
		{
			Pos now(p.x + dir[j].x, p.y + dir[j].y);		//分支
															// 下面若坐标不在范围内会出现超限错误,放后面就不会了
			if (now.x > 0 && now.y > 0 && now.x <= N && now.y <= N && b[now.x][now.y].flag == 2)
			{
				b[now.x][now.y].flag = 1;
				b[now.x][now.y].lenth = b[p.x][p.y].lenth + 1;
				//b[now.x][now.y].mum_x = p.x;			//表示母节点位置
				//b[now.x][now.y].mum_y = p.y;
				store.push(now);
			}
		}
		b[p.x][p.y].flag = 0;
		store.pop();
	}
	long long num = 0;
	for (j = 1; j <= K; j++)
	{
		num += b[Kehu[j].x][Kehu[j].y].lenth * Kehu[j].val;		//最短路径*客户订餐数
	}
	cout << num;
	cin >> N;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/yanpr919/article/details/81183966