zoukankan      html  css  js  c++  java
  • 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;
    }
    
    
    
  • 相关阅读:
    Android 按键消息处理Android 按键消息处理
    objcopy
    SQLite多线程读写实践及常见问题总结
    android动画坐标定义
    Android动画效果translate、scale、alpha、rotate
    Android公共库(缓存 下拉ListView 下载管理Pro 静默安装 root运行 Java公共类)
    Flatten Binary Tree to Linked List
    Distinct Subsequences
    Populating Next Right Pointers in Each Node II
    Populating Next Right Pointers in Each Node
  • 原文地址:https://www.cnblogs.com/smyjr/p/9769482.html
Copyright © 2011-2022 走看看