社区讨论

呼叫超级飞侠

P4009汽车加油行驶问题参与者 8已保存回复 13

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
13 条
当前快照
1 份
快照标识符
@mhjh5k99
此快照首次捕获于
2025/11/04 02:29
4 个月前
此快照最后确认于
2025/11/04 06:18
4 个月前
查看原帖
rt,48pts,num是求编号的函数。
CPP
#include<bits/stdc++.h>
using namespace std;
constexpr long long N=1e2,M=1e5,V=1e18,K=1e1;
long long n,m,dx[]{0,-1,1,0},dy[]{-1,0,0,1};
bitset<N+5> a[N+5];
int k,A,B,C;
struct
{
	int to,nxt,w;
}edge[4*(N+5)*(N+5)*(K+5)];
int head[(N+5)*(N+5)*(K+5)+5],tot;
int num(int x,int y,int z)
{
	return x*(n+1)*(k+1)+y*(k+1)+z;
}
void ad(int u,int v,int w)
{
	edge[++tot]={v,head[u],w};
	head[u]=tot;
}
int dij()
{
	using pr=pair<int,int>;
	static int dis[(N+5)*(N+5)*(K+5)+5];
	static bitset<(N+5)*(N+5)*(K+5)+5> vis;
	priority_queue<pr,vector<pr>,greater<pr>> q;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			for(int p=0;p<=k;p++)
			{
				dis[num(i,j,p)]=INT_MAX;
			}
		}
	}
//	for(int p=0;p<=k;p++) dis[num(1,1,p)]=0;
	dis[num(1,1,k)]=0;
	q.push(make_pair(0,num(1,1,k)));
	while(!q.empty())
	{
		auto t=q.top();q.pop();
		if(vis[t.second]) continue;
		vis[t.second]=1;
		for(int i=head[t.second];i;i=edge[i].nxt)
		{
			const int &to=edge[i].to,&w=edge[i].w;
			if(t.first+w<dis[to])
			{
				dis[to]=t.first+w;
				q.push(make_pair(dis[to],to));
			}
		}
	}
	int mnl=INT_MAX;
	for(int i=0;i<=k;i++) mnl=min(mnl,dis[num(n,n,i)]);
	return mnl;
}
int main()
{
//	freopen("A1.in","r",stdin);
//	freopen(".out","w",stdout);
	cin>>n>>k>>A>>B>>C;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
		{
			int x;cin>>x;
			a[i][j]=x;
		}
//	cout<<num(n,n,k)<<" "<<(N+5)*(N+5)*(K+5)+5<<"\n";
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			for(int p=k;p>0;p--)
			{
				if(p!=k&&a[i][j]) break;
				if(p<k) ad(num(i,j,p),num(i,j,k),C+A);
				for(int r=0;r<2;r++)
				{
					const int &x=i+dx[r],&y=j+dy[r],z=max(p-1,a[x][y]*k);
					if(1<=x&&x<=n&&1<=y&&y<=n&&z>=0)
					
					{
						ad(num(i,j,p),num(x,y,z),B+a[x][y]*A);	
					}	
				}
				for(int r=2;r<4;r++)
				{
					const int &x=i+dx[r],&y=j+dy[r],z=max(p-1,a[x][y]*k);
					if(1<=x&&x<=n&&1<=y&&y<=n&&z>=0)
					{
						ad(num(i,j,p),num(x,y,z),a[x][y]*A);	
					}	
				}
			}
		}
	}
	cout<<dij();
	return 0;
}

回复

13 条回复,欢迎继续交流。

正在加载回复...