CCF CSP 201409-4 最优配餐

思路:

1.学会将多源在一开始时全部加入队列,然后bfs求最优的做法;
2.用一个二维数组表示目前该点离店最近的距离,所有距离初始化为1000*1000以上的值;
3.将所有订单,以坐标和量按序存储起来,之后直接挨个累加就好了;
4.总开销可能会超过int范围,所以可以使用long long;

代码:

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> p;
typedef long long ll;
#define N 1005
#define m_p(a,b) make_pair(a,b)
#define p_b(a) push_back(a)
#define rp(i,n) for(int i=0;i<n;i++)
int n,m,k,d;
ll dist[N][N];//每个客户的最短距离
vector<p> guest;//每个顾客位置 
ll oderNum[N*N];//相应index顾客的配送餐量 
queue<p> q;
void bfs(){
	while(!q.empty()){
		p pos=q.front();
		int x=pos.first,y=pos.second;
		if(x>1&&dist[x-1][y]>dist[x][y]+1){
			q.push(m_p(x-1,y));
			dist[x-1][y]=dist[x][y]+1;
		}
		if(x<n&&dist[x+1][y]>dist[x][y]+1){
			q.push(m_p(x+1,y));
			dist[x+1][y]=dist[x][y]+1;
		}
		if(y>1&&dist[x][y-1]>dist[x][y]+1){
			q.push(m_p(x,y-1));
			dist[x][y-1]=dist[x][y]+1;
		}
		if(y<n&&dist[x][y+1]>dist[x][y]+1){
			q.push(m_p(x,y+1));
			dist[x][y+1]=dist[x][y]+1;
		}
		q.pop();
	}
}
int main(){
	fill(dist[0],dist[0]+N*N,N*N);
	cin>>n>>m>>k>>d;
	rp(i,m){
		int x,y;
		cin>>x>>y;
		dist[x][y]=0;
		q.push(m_p(x,y));
	}
	rp(i,k){
		int x,y,c;
		cin>>x>>y>>c;
		guest.p_b(m_p(x,y));
		oderNum[i]=c;
	}
	rp(i,d){
		int x,y;
		cin>>x>>y;
		dist[x][y]=-1;
	}
	bfs();
	ll ans=0;
	rp(i,k) ans+=dist[guest[i].first][guest[i].second]*oderNum[i];
	cout<<ans;
	return 0;
}
posted @ 2019-10-28 12:02  YuhanのBlog  阅读(303)  评论(0编辑  收藏  举报