解题思路:
明显答案有单调性,故可以使用二分,将灰尘度看为路径长度,可以使用最短路求解。
注意事项:
注意一些限制条件,复杂度(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.0分

1 人评分

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论