zoukankan      html  css  js  c++  java
  • BZOJ1295: [SCOI2009]最长距离

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1295

    windy有一块矩形土地,被分为 N*M 块 1*1 的小格子。 有的格子含有障碍物。 如果从格子A可以走到格子B,那么两个格子的距离就为两个格子中心的欧几里德距离。 如果从格子A不可以走到格子B,就没有距离。 如果格子X和格子Y有公共边,并且X和Y均不含有障碍物,就可以从X走到Y。 如果windy可以移走T块障碍物,求所有格子间的最大距离。 保证移走T块障碍物以后,至少有一个格子不含有障碍物。

    100%的数据,满足 1 <= N,M <= 30 ; 0 <= T <= 30 。

    题解:初看没有思路,因为不知道取掉哪些障碍物并且距离最大的点对是哪个。

              然后我发现,如果不考虑t的限制,显然把 (1,1)和(n,m)之间的障碍去掉,得到最大距离。

              但如果这之间的障碍数>t,那么我们就考虑下一个距离最远的点,直到它们之间的障碍数<=t,那么输出该点对之间的距离。

              如何计算两点之间的障碍数呢?很简单,最短路,将点权作为权值,求最短路。

              多源最短路?floyed?TLE   NO 我们做n次floyed即可。

    代码:

      1 #include<cstdio>
      2 
      3 #include<cstdlib>
      4 
      5 #include<cmath>
      6 
      7 #include<cstring>
      8 
      9 #include<algorithm>
     10 
     11 #include<iostream>
     12 
     13 #include<vector>
     14 
     15 #include<map>
     16 
     17 #include<set>
     18 
     19 #include<queue>
     20 
     21 #include<string>
     22 
     23 #define inf 1000000000
     24 
     25 #define maxn 1000
     26 
     27 #define maxm 500+100
     28 
     29 #define eps 1e-10
     30 
     31 #define ll long long
     32 
     33 #define pa pair<int,int>
     34 
     35 #define for0(i,n) for(int i=0;i<=(n);i++)
     36 
     37 #define for1(i,n) for(int i=1;i<=(n);i++)
     38 
     39 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
     40 
     41 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
     42 
     43 #define mod 1000000007
     44 #define num(i,j) ((i-1)*m+j)
     45 #define sqr(x) (x)*(x)
     46 
     47 using namespace std;
     48 
     49 inline int read()
     50 
     51 {
     52 
     53     int x=0,f=1;char ch=getchar();
     54 
     55     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     56 
     57     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
     58 
     59     return x*f;
     60 
     61 }
     62 int n,m,t,tot,cnt,d[maxn][maxn],a[maxn],head[maxn];
     63 const int dx[4]={0,0,1,-1};
     64 const int dy[4]={1,-1,0,0};
     65 bool v[maxn];
     66 struct edge{int go,next;}e[4*maxn];
     67 struct rec{double x;int y;}b[maxn*maxn];
     68 priority_queue<pa,vector<pa>,greater<pa> >q;
     69 inline void insert(int x,int y)
     70 {
     71     e[++tot].go=y;e[tot].next=head[x];head[x]=tot;
     72 }
     73 inline void dijkstra(int s)
     74 {
     75     for1(i,n*m)d[s][i]=inf,v[i]=0;
     76     d[s][s]=a[s];
     77     q.push(pa(d[s][s],s));
     78     while(!q.empty())
     79     {
     80         int x=q.top().second;q.pop();if(v[x])continue;v[x]=1;
     81         for(int i=head[x],y;i;i=e[i].next)
     82             if(d[s][x]+a[y=e[i].go]<d[s][y])
     83             {
     84                 d[s][y]=d[s][x]+a[y];
     85                 q.push(pa(d[s][y],y));
     86             }
     87     }
     88 }
     89 inline bool cmp(rec a,rec b){return a.x>b.x;}
     90 
     91 int main()
     92 
     93 {
     94 
     95     freopen("input.txt","r",stdin);
     96 
     97     freopen("output.txt","w",stdout);
     98 
     99     n=read();m=read();t=read();
    100     for1(i,n*m)
    101     {
    102         char ch=' ';
    103         while(ch!='0'&&ch!='1')ch=getchar();
    104         a[i]=ch-'0';
    105     }
    106     for1(i,n)
    107      for1(j,m)
    108       for0(k,3)
    109        {
    110          int ii=i+dx[k],jj=j+dy[k];
    111          if(ii<1||ii>n||jj<1||jj>m)continue;
    112          insert(num(i,j),num(ii,jj));
    113        }
    114     for1(i,n*m)dijkstra(i);
    115     for1(i,n)
    116      for1(j,m)
    117       for1(ii,n)
    118         for1(jj,m)
    119          b[++cnt].x=sqrt(sqr(i-ii)+sqr(j-jj)),b[cnt].y=d[num(i,j)][num(ii,jj)];
    120     sort(b+1,b+cnt+1,cmp);
    121     int ans=1;
    122     while(b[ans].y>t)ans++;
    123     printf("%.6f
    ",b[ans].x);
    124 
    125     return 0;
    126 
    127 }
    View Code

     UPD:看题解发现b数组不用存下来排序,暴力枚举更新答案即可。

    代码:

      1 #include<cstdio>
      2 
      3 #include<cstdlib>
      4 
      5 #include<cmath>
      6 
      7 #include<cstring>
      8 
      9 #include<algorithm>
     10 
     11 #include<iostream>
     12 
     13 #include<vector>
     14 
     15 #include<map>
     16 
     17 #include<set>
     18 
     19 #include<queue>
     20 
     21 #include<string>
     22 
     23 #define inf 1000000000
     24 
     25 #define maxn 1000
     26 
     27 #define maxm 500+100
     28 
     29 #define eps 1e-10
     30 
     31 #define ll long long
     32 
     33 #define pa pair<int,int>
     34 
     35 #define for0(i,n) for(int i=0;i<=(n);i++)
     36 
     37 #define for1(i,n) for(int i=1;i<=(n);i++)
     38 
     39 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
     40 
     41 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
     42 
     43 #define mod 1000000007
     44 #define num(i,j) ((i-1)*m+j)
     45 #define sqr(x) (x)*(x)
     46 
     47 using namespace std;
     48 
     49 inline int read()
     50 
     51 {
     52 
     53     int x=0,f=1;char ch=getchar();
     54 
     55     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     56 
     57     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
     58 
     59     return x*f;
     60 
     61 }
     62 int n,m,t,tot,cnt,d[maxn][maxn],a[maxn],head[maxn];
     63 const int dx[4]={0,0,1,-1};
     64 const int dy[4]={1,-1,0,0};
     65 bool v[maxn];
     66 struct edge{int go,next;}e[4*maxn];
     67 priority_queue<pa,vector<pa>,greater<pa> >q;
     68 inline void insert(int x,int y)
     69 {
     70     e[++tot].go=y;e[tot].next=head[x];head[x]=tot;
     71 }
     72 inline void dijkstra(int s)
     73 {
     74     for1(i,n*m)d[s][i]=inf,v[i]=0;
     75     d[s][s]=a[s];
     76     q.push(pa(d[s][s],s));
     77     while(!q.empty())
     78     {
     79         int x=q.top().second;q.pop();if(v[x])continue;v[x]=1;
     80         for(int i=head[x],y;i;i=e[i].next)
     81             if(d[s][x]+a[y=e[i].go]<d[s][y])
     82             {
     83                 d[s][y]=d[s][x]+a[y];
     84                 q.push(pa(d[s][y],y));
     85             }
     86     }
     87 }
     88 
     89 int main()
     90 
     91 {
     92 
     93     freopen("input.txt","r",stdin);
     94 
     95     freopen("output.txt","w",stdout);
     96 
     97     n=read();m=read();t=read();
     98     for1(i,n*m)
     99     {
    100         char ch=' ';
    101         while(ch!='0'&&ch!='1')ch=getchar();
    102         a[i]=ch-'0';
    103     }
    104     for1(i,n)
    105      for1(j,m)
    106       for0(k,3)
    107        {
    108          int ii=i+dx[k],jj=j+dy[k];
    109          if(ii<1||ii>n||jj<1||jj>m)continue;
    110          insert(num(i,j),num(ii,jj));
    111        }
    112     for1(i,n*m)dijkstra(i);
    113     double ans=0.0;
    114     for1(i,n)
    115      for1(j,m)
    116       for1(ii,n)
    117        for1(jj,m)
    118         if(d[num(i,j)][num(ii,jj)]<=t)ans=max(ans,sqrt(sqr(i-ii)+sqr(j-jj)));
    119     printf("%.6f
    ",ans);
    120 
    121     return 0;
    122 
    123 }
    View Code

    还有此题SPFA貌似更快?不过好像是网格图唉。。。

  • 相关阅读:
    SDUST OJ 时间类的加、减法赋值运算
    POJ 2823 (滑动窗口)
    POJ 2229 计数DP
    POJ 1995 (快速幂)
    poj 3009 (深搜求最短路)
    C++ 学习笔记之 STL 队列
    C++ 学习笔记之 引用
    Anaconda3使用
    Ubuntu 18.04安装Conda、Jupyter Notebook、Anaconda
    Ubuntu 18.04安装 pyenv、pyenv-virtualenv、virtualenv、Numpy、SciPy、Pillow、Matplotlib
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/4089651.html
Copyright © 2011-2022 走看看