P7997 [WFOI - 01] 刷题(bfs)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P7997 [WFOI - 01] 刷题(bfs)相关的知识,希望对你有一定的参考价值。

P7997 [WFOI - 01] 刷题(bfs)

容易知道到达的值范围是 [ 0 , 2 × m x ) [0,2\\times mx) [0,2×mx)

考虑把每个值当作点,然后拆点。

分别表示奇数次到达 [ 0 , 4000 ) [0,4000) [0,4000)和偶数次到达的点 [ 4000 , 8000 ) [4000,8000) [4000,8000)

建边

void add(int u,int v)
	e[++cnt]=v+4000,h[u],h[u]=cnt;
	e[++cnt]=v,h[u+4000],h[u+4000]=cnt;

for(int i=0;i<mx;i++)
		rep(j,1,n)
				if(i>=a[j]) add(i,i-a[j]);
				else add(i,i+a[j]);

然后从 4000 4000 4000出发,跑最短路。

代码如下:

// Problem: P7997 [WFOI - 01]  刷题 (problem)
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P7997
// Memory Limit: 512 MB
// Time Limit: 1000 ms
// Date: 2022-01-07 12:06:31
// --------by Herio--------

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=2e3+5,M=1e4+5,inf=0x3f3f3f3f,mod=1e9+7;
const int hashmod[4] = 402653189,805306457,1610612741,998244353;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define x first
#define y second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define ios ios::sync_with_stdio(false),cin.tie(nullptr) 
void Print(int *a,int n)
	for(int i=1;i<n;i++)
		printf("%d ",a[i]);
	printf("%d\\n",a[n]); 

template <typename T>		//x=max(x,y)  x=min(x,y)
void cmx(T &x,T y)
	if(x<y) x=y;

template <typename T>
void cmn(T &x,T y)
	if(x>y) x=y;

int h[M],cnt;
struct node
	int to,nt;
e[M*2000];
void add(int u,int v)
	e[++cnt]=v+4000,h[u],h[u]=cnt;
	e[++cnt]=v,h[u+4000],h[u+4000]=cnt;

ll f[M];
int a[N],mx;
//4000*2000*2
int main()
	int n,t;
	scanf("%d%d",&n,&t);
	rep(i,1,n) scanf("%d",&a[i]),cmx(mx,a[i]);
	mx<<=1;
	for(int i=0;i<mx;i++)
		rep(j,1,n)
				if(i>=a[j]) add(i,i-a[j]);
				else add(i,i+a[j]);
	mst(f,0x3f);
	f[4000] = 0;
	queue<int>q;q.push(4000);
	while(!q.empty())
		int u = q.front();q.pop();
		for(int i=h[u];i;i=e[i].nt)
			int v = e[i].to;
			if(f[v]>f[u]+1)
			
				f[v] = f[u] + 1;
				q.push(v);
			
		
	
	while(t--)
		ll x;scanf("%lld",&x);
		//printf("x=%lld\\n",x);
		if(x&1)
			for(int i=3999;i>=0;--i)
				if(f[i]<=x)
					printf("%d\\n",i);break;
				
			
		
		else 
			for(int i=7999;i>=4000;--i)
				if(f[i]<=x)
					printf("%d\\n",i-4000);break;
				
						
		
	
	return 0;
;

以上是关于P7997 [WFOI - 01] 刷题(bfs)的主要内容,如果未能解决你的问题,请参考以下文章

AcWing刷题蓝桥杯专题突破-广度优先搜索-bfs(11)

leetcode之DFS+BFS+DSU刷题总结2

洛谷刷题蓝桥杯专题突破-广度优先搜索-bfs(16)

BFS: 刷题专用

刷题bfs最优贸易

面试刷题:广度优先搜索BFS | 第91期