CCF 201409-4 最优配餐 100分(bfs)

Posted 登登登ccc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CCF 201409-4 最优配餐 100分(bfs)相关的知识,希望对你有一定的参考价值。

题目来源:- 计算机软件能力认证考试系统

刚开始的思路:将每个收货点作为目标点,把送货点全部入队列,进行bfs,每次计算出一个结果,把每次迭代的结果相加得出最后答案。这种思路会导致运行超时,可能因为迭代次数过多。

60分代码:

#include<bits/stdc++.h>

using namespace std;
const int MAX=1000;
int n,m,k,d;
bool visited[MAX+10][MAX+10];
int dirX[]= {-1,1,0,0};
int dirY[]= {0,0,-1,1};
int weight[MAX+10];

struct Map {
	int x,y,sum;
	Map() {}
	Map(int xx, int yy, int s=0):x(xx),y(yy),sum(s) {}
} sell[MAX*MAX+10],buy[MAX*MAX+10],del[MAX*MAX+10];

int BFS(int destx, int desty, int destw) {
	queue<Map> q;
	
	memset(visited,false,sizeof(visited)); //每次bfs都重新初始化访问标记数组
	for(int i=1; i<=d; i++)
		visited[del[i].x][del[i].y]=true;

	for(int i=1; i<=m; i++)     //每次bfs都要将送货点入队
		q.push(sell[i]);

	while(!q.empty()) {
		Map cur=q.front();
		q.pop();
		visited[cur.x][cur.y]=true;

		if(cur.x==destx && cur.y==desty)
			return cur.sum*destw;

		for(int i=0; i<4; i++) {
			int x=cur.x+dirX[i],y=cur.y+dirY[i];
			if(x<1 || x>n || y<1 || y>n || visited[x][y])
				continue;
				
			visited[x][y]=true;
			q.push(Map(x,y,cur.sum+1));
		}
	}
	return 0;
}

int main() {

	cin>>n>>m>>k>>d;
	int x,y,w;
	for(int i=1; i<=m; i++) {
		cin>>x>>y;
		sell[i]=Map(x,y);
	}

	for(int i=1; i<=k; i++) {
		cin>>x>>y>>weight[i];
		buy[i]=Map(x,y);
	}
	
	for(int i=1; i<=d; i++) {
		cin>>x>>y;
		del[i]=Map(x,y);
	}
	
	long long ans=0;
	for(int i=1; i<=k; i++)
		ans+=BFS(buy[i].x, buy[i].y, weight[i]); //将每次bfs的结果相加得到答案

	cout<<ans;
	return 0;
}

 

改进:将所有送货点在输入时就全部入队,使用一个权重数组,记录收货点的权重,不是收货点的权重记为0。这样每次遍历到不是收货点的结点,只会加0,而不是加对应的权重*距离。

100分代码:

#include<bits/stdc++.h>

using namespace std;

const int MAX=1005;
int n,m,k,d;
bool visited[MAX][MAX];
int dirX[]= {-1,1,0,0};
int dirY[]= {0,0,-1,1};
long long weight[MAX][MAX];

struct Map {
	int x,y;
	long long sum;
	Map(int xx, int yy, int s=0):x(xx),y(yy),sum(s) {}
};

queue<Map> q;

long long BFS() {
	long long ans=0;
	
	while(!q.empty()) {
		Map cur=q.front();
		q.pop();
		visited[cur.x][cur.y]=true;

		for(int i=0; i<4; i++) {
			int x=cur.x+dirX[i],y=cur.y+dirY[i];
			if(x<1 || x>n || y<1 || y>n || visited[x][y])
				continue;
				
			visited[x][y]=true;
			ans+=weight[x][y]*(cur.sum+1);  //下一个结点不是收货点就加0,是收货点就加权重*距离
			q.push(Map(x,y,cur.sum+1));
		}
	}
	return ans;
}


int main() {
	ios::sync_with_stdio(false);
	
	cin>>n>>m>>k>>d;
	int x,y,w;
	for(int i=1; i<=m; i++) {
		cin>>x>>y;
		q.push(Map(x,y));  //在输入时就全部入队
	}

	for(int i=1; i<=k; i++) {
		cin>>x>>y>>w;
		weight[x][y]+=w;   //可能有多个收货点在同一坐标,权重要累积计算
	}
	
	for(int i=1; i<=d; i++) {
		cin>>x>>y;
		visited[x][y]=true; //记录不可达结点
	}

	cout<<BFS();
	return 0;
}

以上是关于CCF 201409-4 最优配餐 100分(bfs)的主要内容,如果未能解决你的问题,请参考以下文章

CCF 201409-4 最优配餐 100分(bfs)

CCF 201409-4 最优配餐 100分(bfs)

CCF 201409-4 最优配餐

CCF 201409-4 最优配餐

CCF 201409-4 最优配餐

CCF 201409-4 最优配餐