【ccf-csp题解】第2次csp认证-第四题-最优配餐-多源BFS

题目描述

思路讲解

这道题的数据量是10^6,直接用floyd算法,肯定是不行的

此处介绍新的思路:多源BFS

我们的核心目的是,对于每一个终点(即此处的顾客)能够找到离它最近的源点(即此处的餐馆)

思路如下,我们假想一个"超级源点"S,如图所示:

这个超级遇到源点距离每一个源点为0

那么算某个终点(比如A)到源点A,B,C,D的最短距离,就可以转换为求A到S的距离

代码应该怎么实现呢?

很简单,假设提前已经把S入队了,直接进入下一步:S出队,然后入队源点A,B,C,D即可

其它和普通BFS一毛一样

时间复杂度:O(N)

最后注意,答案可能爆int,所以用longlong

满分代码

cpp 复制代码
#include<iostream>
#include<queue>
#include<utility>
#include<cstring>
using namespace std;
const int N=1010;
typedef long long LL;
typedef pair<int,int>PII;
queue<PII>q;
int n,m,d,k;
int dist[N][N];
struct Target{
	int x,y,c;
}target[N*N];
LL res=0;
bool trap[N][N];
void bfs()
{
	int dx[]={-1,0,1,0},dy[]={0,1,0,-1};
	while(q.size())
	{
		auto t=q.front();
		q.pop();
		for(int i=0;i<4;i++)
		{
			int a=t.first+dx[i],b=t.second+dy[i];
			if(a<1||a>n||b<1||b>n||trap[a][b])continue;
			if(dist[a][b]>dist[t.first][t.second]+1)
			{
				dist[a][b]=dist[t.first][t.second]+1;
				q.push({a,b});
			}
		}
	}
}
int main()
{
	scanf("%d%d%d%d",&n,&m,&k,&d);
	memset(dist,0x3f,sizeof dist);
	for(int i=1;i<=m;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		q.push({x,y});
		dist[x][y]=0;
	}
	for(int i=1;i<=k;i++)
	{
		int x,y,c;
		scanf("%d%d%d",&x,&y,&c);
		target[i].x=x,target[i].y=y,target[i].c=c;
	}
	for(int i=1;i<=d;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		trap[x][y]=true;
	}
	bfs();
	for(int i=1;i<=k;i++)
	res+=(LL)dist[target[i].x][target[i].y]*target[i].c;
	cout<<res;
	return 0;
}
相关推荐
坚持编程的菜鸟4 小时前
LeetCode每日一题——困于环中的机器人
c语言·算法·leetcode·机器人
Aurorar0rua5 小时前
C Primer Plus Notes 09
java·c语言·算法
史迪奇_xxx7 小时前
10、一个简易 vector:C++ 模板与 STL
java·开发语言·c++
我不是QI8 小时前
DES 加密算法:核心组件、加解密流程与安全特性
经验分享·算法·安全·网络安全·密码学
前端小刘哥8 小时前
新版视频直播点播EasyDSS平台,让跨团队沟通高效又顺畅
算法
我是华为OD~HR~栗栗呀9 小时前
华为od-21届考研-C++面经
java·c语言·c++·python·华为od·华为·面试
oioihoii9 小时前
C++ 中的类型转换:深入理解 static_cast 与 C风格转换的本质区别
java·c语言·c++
明月(Alioo)9 小时前
机器学习入门,无监督学习之K-Means聚类算法完全指南:面向Java开发者的Python实现详解
python·算法·机器学习
叶梅树9 小时前
从零构建A股量化交易工具:基于Qlib的全栈系统指南
前端·后端·算法
小妖6669 小时前
vscode 怎么运行 c++ 文件
开发语言·c++