#Floyd分治# [Ybtoj NOIP2020 模拟赛 B 组 Day7]路径之和

Title

大意:询问不经过 k ∈ [ 1 , n ] k\in [1,n] k[1,n],任意有序数对 ( l , k , r ) (l,k,r) (l,k,r)的最短路和。


Solution

在这里插入图片描述


Code

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#define ll long long
#define rep(i,x,y) for(int i=x;i<=y;i++)
using namespace std; 
const int N=400,INF=0x3f3f3f3f; 
int n,a[30][N][N]; ll ans; 
int read(){
	int p=0,f=1;char c=getchar();
	while (!isdigit(c)) {if (c=='-')  f=-1; c=getchar();}
	while (isdigit(c)) p=(p<<3)+(p<<1)+c-48,c=getchar(); 
	return p*f; 
}
void solve(int l,int r,int dep){
	if (l==r){
		rep(i,1,n) rep(j,1,n) if (i!=l&&j!=l) if (a[dep][i][j]<INF) ans+=a[dep][i][j]; else ans+=-1; 
		return;
	}
	memcpy(a[dep+1],a[dep],sizeof(a[dep])); 
	int mid=(l+r)>>1; 
	rep(k,l,mid) rep(i,1,n) rep(j,1,n) if (i!=k&&i!=j&&j!=k) a[dep+1][i][j]=min(a[dep+1][i][j],a[dep+1][i][k]+a[dep+1][k][j]); 
	solve(mid+1,r,dep+1); 
	memcpy(a[dep+1],a[dep],sizeof(a[dep])); 
	rep(k,mid+1,r) rep(i,1,n) rep(j,1,n) if (i!=k&&i!=j&&j!=k) a[dep+1][i][j]=min(a[dep+1][i][j],a[dep+1][i][k]+a[dep+1][k][j]); 
	solve(l,mid,dep+1); 
}
int main(){
	freopen("sum.in","r",stdin); 
	freopen("sum.out","w",stdout); 
	n=read(); 
	rep(i,1,n) rep(j,1,n){
		int x=read(); 
		if (x!=-1) a[0][i][j]=x; else a[0][i][j]=INF; 
	}
	solve(1,n,0); 
	printf("%lld",ans); 
	return 0; 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值