点击跳转例题
思路:
因为时间满足单调性,二段性,所以可以二分时间。
因为要求任意两点的最小值,所以用Floyd(check函数)代码:
#include <bits/stdc++.h> #define int long long //(有超时风险) #define PII pair<int,int> #define endl '\n' #define LL __int128 using namespace std; const int N=2e5+10,M=2e2+10,mod=998244353,INF=0x3f3f3f3f; int d[M][M]; int limit[M][M]; int tmp[M][M]; signed main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int n,Q;cin>>n>>Q; for(int i=0;i<n;i++) for(int j=0;j<n;j++) cin>>d[i][j]; for(int i=0;i<n;i++) for(int j=0;j<n;j++) cin>>limit[i][j]; auto check=[&](int mid) { //利用备份的数组,方便操作。 for(int i=0;i<n;i++) for(int j=0;j<n;j++) tmp[i][j]=d[i][j]; for(int i=0;i<n;i++) { //计算时间带来的对道路的影响。 int val=mid/n+(mid%n>=i+1?1:0); for(int j=0;j<n;j++) { //因为影响自身和相连的点,所以*2 tmp[i][j]=max(tmp[i][j]-val*2,limit[i][j]); } } for(int k=0;k<n;k++) for(int i=0;i<n;i++) for(int j=0;j<n;j++) { if(tmp[i][j]>tmp[i][k]+tmp[k][j]) tmp[i][j]=tmp[i][k]+tmp[k][j]; } int sum=0; for(int i=0;i<n;i++) for(int j=0;j<n;j++) sum+=tmp[i][j]; return sum<=Q; }; int l=0,r=1e6*n; int ans=-1; while(l<r) { int mid=(l+r)/2; if(check(mid)) { r=mid; ans=mid; } else l=mid+1; } cout<<ans<<endl; return 0; }
P8794 [蓝桥杯 2022 国 A] 环境治理--2024蓝桥杯冲刺省一
最新推荐文章于 2024-07-10 16:47:58 发布