最优配餐
问题
问题描述
试题编号: | 201409-4 |
试题名称: | 最优配餐 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 栋栋最近开了一家餐饮连锁店,提供外卖服务。随着连锁店越来越多,怎么合理的给客户送餐成为了一个急需解决的问题。 输入格式 输入的第一行包含四个整数n, m, k, d,分别表示方格图的大小、栋栋的分店数量、客户的数量,以及不能经过的点的数量。 输出格式 输出一个整数,表示最优送餐方式下所需要花费的成本。 样例输入 10 2 3 3 样例输出 29 评测用例规模与约定 前30%的评测用例满足:1<=n <=20。 |
解题思路
此题是最短路径求解问题,由于不知道所有的配餐位置,因此我们首先找到所有点的单份最佳配送费用。通过广度优先搜索来进行求解,采用优先队列优先选出消费最小的点即可。最后遍历所有位置进行处理。
90分。
代码实现
#include <iostream>
#include <cstring>
#include<queue>
#include <vector>
#define rep(i,s,e) for(int i = s;i<e;i++)
using namespace std;
const int maxSize = 1005;
int dx[4] = {0,0,-1,1};
int dy[4] = {1,-1,0,0};
//存放地图
int mp[maxSize][maxSize];
//存放路费
int vis[maxSize][maxSize];
int waiMais[maxSize][maxSize];
int n,m,k,d;
struct Shop{
int x;
int y;
};
struct Consume{
int x;
int y;
int money;
friend bool operator < (Consume c1,Consume c2){
return c1.money > c2.money;
}
};
//vector<WaiMai>waiMais;
vector<Shop>shops;
//判断是否可走
int judge(int x,int y){
if(x>=1&&x<=n&&y>=1&&y<=n&&mp[x][y]==0){
return 1;
}
else return 0;
}
void bfs(){
int len = shops.size();
priority_queue<Consume>q;
rep(i,0,len){
Consume c;
c.x = shops[i].x;
c.y = shops[i].y;
c.money = 0;
q.push(c);
}
while(!q.empty()){
Consume c = q.top();
q.pop();
rep(i,0,4){
int x = c.x+dx[i];
int y = c.y+dy[i];
int money = c.money+1;
if(judge(x,y)){
if(vis[x][y]>money||vis[x][y]==-1){
Consume c2;
vis[x][y] = money;
c2.x = x;
c2.y = y;
c2.money = money;
q.push(c2);
}
}
}
}
}
int main(){
rep(i,0,maxSize){
rep(j,0,maxSize){
vis[i][j] = -1;
}
}
cin>>n>>m>>k>>d;
rep(i,0,m){
Shop shop ;
cin>>shop.x>>shop.y;
vis[shop.x][shop.y] = 0;
shops.push_back(shop);
}
rep(i,0,k){
int x,y,num;
cin>>x>>y>>num;
waiMais[x][y] +=num;
}
rep(i,0,d){
int x,y;
cin>>x>>y;
mp[x][y] = 1;
}
int len = shops.size();
bfs();
long long sum = 0;
rep(i,1,n+1){
rep(j,1,n+1){
//cout<<vis[i][j];
//cout<<mp[i][j];
sum += waiMais[i][j]*vis[i][j];
}
// cout<<endl;
}
cout<<sum<<endl;
}