[25BJWCB2A]最优化(网格图最短路)
题目大意
详细题目传送门
给一个
思路
首先想利用网格图和这个
我们考虑维护列数,线段树
其中
于是我们就可以维护出任意一个
发现
之后再用
最后时间复杂度可以做到
代码
#include<bits/stdc++.h>
#define rep(i,a,b) for(register int i=(a);i<=(b);++i)
#define endl '\n'
using namespace std;
typedef long long ll;
const ll MAXN=1e5+3;
const ll MAXM=12;
int m,n,Q,A[MAXM][MAXN],B[MAXM][MAXN];
struct node{
ll l,r,c[MAXM][MAXM];
#define lc(u) (u<<1)
#define rc(u) (u<<1|1)
}t[MAXN*4];
ll ans[MAXM],sans[MAXN];
inline void merge(ll u,ll l,bool fst){
rep(i,1,m){
sans[i]=1e18;
}
rep(j,1,m){
rep(i,1,m){
sans[i]=min(sans[i],ans[j]+(fst?0:A[j][l-1])+t[u].c[j][i]);
}
}
rep(i,1,m){
ans[i]=sans[i];
}
}
inline void push_up(ll u){
rep(i,1,m){
rep(j,1,m){
t[u].c[i][j]=1e18;
}
}
rep(k,1,m){
rep(i,1,m){
rep(j,1,m){
t[u].c[i][j]=min(t[u].c[i][j],t[lc(u)].c[i][k]+A[k][(t[u].l+t[u].r)>>1]+t[rc(u)].c[k][j]);
}
}
}
}
ll L[MAXN][MAXM][MAXM],R[MAXN][MAXM][MAXM];
ll v[MAXN][MAXM][MAXM];
void floyd_f(ll id){
rep(k,1,m){
rep(i,1,m){
rep(j,1,m){
v[id][i][j]=min(v[id][i][j],v[id][i][k]+v[id][k][j]);
}
}
}
}
void floyd(ll id,bool r){
if(!r){
rep(k,1,m){
rep(i,1,m){
rep(j,1,m){
L[id][i][j]=min(L[id][i][j],L[id][i][k]+L[id][k][j]);
}
}
}
return;
}
rep(k,1,m){
rep(i,1,m){
rep(j,1,m){
R[id][i][j]=min(R[id][i][j],R[id][i][k]+R[id][k][j]);
}
}
}
}
void build(ll u,ll l,ll r){
t[u].l=l;
t[u].r=r;
if(l==r){
memcpy(t[u].c,v[l],sizeof t[u].c);
return;
}
ll mid=(l+r)>>1;
build(lc(u),l,mid);
build(rc(u),mid+1,r);
push_up(u);
}
void query(ll u,ll l,ll r,ll ql,ll qr){
if(ql<=l&&r<=qr){
merge(u,l,l==ql);
return;
}
ll mid=(l+r)>>1;
if(ql<=mid){
query(lc(u),l,mid,ql,qr);
}
if(mid+1<=qr){
query(rc(u),mid+1,r,ql,qr);
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>m>>n>>Q;
rep(i,1,m){
rep(j,1,n-1){
cin>>A[i][j];
}
}
rep(i,1,m-1){
rep(j,1,n){
cin>>B[i][j];
}
}
memset(L,0x3f,sizeof L);
memset(R,0x3f,sizeof R);
rep(i,1,n){
memcpy(L[i],L[i-1],sizeof L[i]);
if(i>1){
rep(j,1,m){
rep(k,1,m){
L[i][j][k]+=A[j][i-1]+A[k][i-1];
}
}
}
rep(j,1,m){
L[i][j][j]=0;
L[i][j][j+1]=L[i][j+1][j]=min(L[i][j][j+1],ll(B[j][i]));
}
floyd(i,0);
}
for(int i=n;i>=1;--i){
memcpy(R[i],R[i+1],sizeof R[i]);
if(i<n){
rep(j,1,m){
rep(k,1,m){
R[i][j][k]+=A[j][i]+A[k][i];
}
}
}
rep(j,1,m){
R[i][j][j]=0;
R[i][j][j+1]=R[i][j+1][j]=min(R[i][j][j+1],ll(B[j][i]));
}
floyd(i,1);
rep(j,1,m){
rep(k,1,m){
v[i][j][k]=min(L[i][j][k],R[i][j][k]);
}
}
floyd_f(i);
}
build(1,1,n);
rep(_,1,Q){
ll a,b,p,q;
cin>>a>>b>>p>>q;
if(b>q){
swap(a,p);
swap(b,q);
}
memset(ans,0x3f,sizeof ans);
ans[a]=0;
query(1,1,n,b,q);
cout<<ans[p]<<endl;
}
return 0;
}
__EOF__
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek-R1本地部署如何选择适合你的版本?看这里
· 开源的 DeepSeek-R1「GitHub 热点速览」
· 传国玉玺易主,ai.com竟然跳转到国产AI
· 揭秘 Sdcb Chats 如何解析 DeepSeek-R1 思维链
· 自己如何在本地电脑从零搭建DeepSeek!手把手教学,快来看看! (建议收藏)