解题思路:
明显答案有单调性,故可以使用二分,将灰尘度看为路径长度,可以使用最短路求解。
注意事项:
注意一些限制条件,复杂度(O(n^3logm))。
参考代码:
#include
using namespace std;
#define maxx 101000
#define int long long
#define INF 0x3f3f3f3f
int n,Q,l=0,r=0;
int G[102][102];
int all[102][102];
int lim[102][102];
int check(int i)
{
int now=(i-1)%n;
int sum=(i-1)/n;
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
all[i][j]=G[i][j];
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
{if(i<=now) --all[i][j];
if(j<=now) --all[i][j];
all[i][j]=all[i][j]-2*sum;
all[i][j]=max(all[i][j],lim[i][j]);
}
for(int k=0;k<n;++k)
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
all[i][j]=min(all[i][j],all[i][k]+all[k][j]);
int ans=0;
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
ans+=all[i][j];
if(ans<=Q) return 1;
else return 0;
}
signed main()
{
cin>>n>>Q;
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
cin>>G[i][j];
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
cin>>lim[i][j];
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
r=max(r,G[i][j]-lim[i][j]);
r=r*n;
if(!check(r)) {cout<<"-1"; return 0;}
if(check(l)) {cout<<"0";return 0;}
while(l<r)
{
int mid=(l+r)/2;
if(!check(mid)) l=mid+1;
else r=mid;
}
cout<<l;
}
0.0分
1 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复