1. 程式人生 > >luogu P4162 [SCOI2009]最長距離

luogu P4162 [SCOI2009]最長距離

its c++ char add long long sco pro 是否 pop

傳送門

可以枚舉兩個點然後計算答案,至於是否合法,就要看可不可以通過移不超過\(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\n",sqrt(ans));
  return 0;
}

luogu P4162 [SCOI2009]最長距離