luogu P4162 [SCOI2009]最长距离

Posted smyjr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu P4162 [SCOI2009]最长距离相关的知识,希望对你有一定的参考价值。

传送门

可以枚举两个点然后计算答案,至于是否合法,就要看可不可以通过移不超过(t)个箱子使得两点连通,也可以看做找一条路径使得路径上的1个数不超过(t)

所以可以考虑最短路,相邻的点两两连边,如果边的末端是1,那么边权为1,否则为0,再对每个点求单源最短路,注意初始距离为点上的数字(0/1)

最后就看两个点跑出来的距离是否(leq t)救星了

神tm洛谷上不开o2跑得飞慢,比bzoj还慢qwq

// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define LL long long
#define il inline
#define re register
#define db double
#define eps (1e-5)

using namespace std;
const int N=35,M=900+10;
il LL rd()
{
    re LL x=0,w=1;re char ch;
    while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    return x*w;
}
int to[M<<2],nt[M<<2],w[M<<2],hd[M],tot=1;
il void add(int x,int y,int z){++tot,to[tot]=y,nt[tot]=hd[x],w[tot]=z,hd[x]=tot;}
struct node
{
  int x,d;
  bool operator < (const node &bb) const {return d>bb.d;}
};
int n,m,kk,id[N][N],a[N][N],di[M][M];
db ans;

int main()
{
  n=rd(),m=rd(),kk=rd();
  char cc[N];
  for(int i=1;i<=n;i++)
    {
      scanf("%s",cc+1);
      for(int j=1;j<=m;j++)
        id[i][j]=(i-1)*m+j,a[i][j]=cc[j]-'0';
    }
  for(int i=1;i<=n;i++)
    {
      for(int j=1;j<=m;j++)
        {
          if(i>1) add(id[i-1][j],id[i][j],a[i][j]);
          if(i<n) add(id[i+1][j],id[i][j],a[i][j]);
          if(j>1) add(id[i][j-1],id[i][j],a[i][j]);
          if(j<m) add(id[i][j+1],id[i][j],a[i][j]);
        }
    }
  for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
      {
        int ss=id[i][j];
        memset(di[ss],63,sizeof(di[ss]));
        di[ss][ss]=a[i][j];
        priority_queue<node> q;
        q.push((node){ss,a[i][j]});
        while(!q.empty())
          {
            int x=q.top().x,d=q.top().d;
            q.pop();
            if(d>di[ss][x]) continue;
            for(int i=hd[x];i;i=nt[i])
              {
                int y=to[i];
                if(di[ss][y]>di[ss][x]+w[i])
                  {
                    di[ss][y]=di[ss][x]+w[i];
                    q.push((node){y,di[ss][y]});
                  }
              }
          }
      }
  for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
      for(int k=1;k<=n;k++)
        for(int l=1;l<=m;l++)
          if(di[id[i][j]][id[k][l]]<=kk) ans=max(ans,(db)(i-k)*(db)(i-k)+(db)(j-l)*(db)(j-l));
  printf("%.6lf
",sqrt(ans));
  return 0;
}

以上是关于luogu P4162 [SCOI2009]最长距离的主要内容,如果未能解决你的问题,请参考以下文章

[luogu4162 SCOI2009] 最长距离(最短路)

luogu2564 [SCOI2009]生日礼物

BZOJ 1295 Scoi2009 最长距离

bzoj 1295 [SCOI2009]最长距离 最短路

[BZOJ1295][SCOI2009]最长距离 最短路+枚举

bzoj 1295: [SCOI2009]最长距离