【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;
}
相关推荐
QiLinkOS1 小时前
第三视觉理解徐玉生与他的商业活动(28)
大数据·c++·人工智能·算法·开源协议
星夜夏空991 小时前
C++学习(2) —— 类与对象基础
开发语言·c++·学习
wabs6662 小时前
关于动态规划【力扣1143.最长公共子序列的思考】
算法·leetcode·动态规划
剑挑星河月2 小时前
54.螺旋矩阵
java·算法·leetcode·矩阵
Robot_Nav2 小时前
MPPI 局部规划器实验设计讲解
人工智能·算法·mppi
mingo_敏3 小时前
Mean-Teacher 均值教师自训练框架详解
算法·均值算法
会周易的程序员3 小时前
microLog 后端开发指南
开发语言·c++·物联网·设计模式·日志·iot·aiot
星空露珠3 小时前
迷你世界UGc3.0脚本Wiki[剧情动画模块管理接口 Timeline]
开发语言·数据结构·算法·游戏·lua
笨笨没好名字3 小时前
Leetcode刷题python3版第一周(下)
linux·算法·leetcode
汉克老师3 小时前
GESP2026年6月认证C++二级( 第三部分编程题(2、菱形))精讲
c++·找规律·绘制图形·对角线·双重循环