• 二分+最短路判定 BZOJ 2709: [Violet 1]迷宫花园


     BZOJ 2709: [Violet 1]迷宫花园

    
    

    Sample Input


    5
    10.28 9 9 ######### # # # # # # # #S# # ##### # # ## # # # ### ### ##E # ######### 4.67 9 9 ######### # ## ## ### #S# # # # E ## # # ##### # ## ### # ##### # # # # ######### 39.06 9 9 ######### # # # # # # # # E# # # # # # # # ## ### # # # #S# # ##### # ######### 24.00 9 9 ######### # ## # # ## ## # # ## ###S## E# ### # ## # # # # ##### # # ######### 25.28 9 9 ######### # S##E# # # ### # # # ## # # ## ### # # #### # # # ### # # ######### Sample Output 0.41000 4.67000 3.34000 5.00000 1.69000

    HINT

      1 /*
      2 分析:符合二分的原理:当v变大,dis一定变大,而且v的具体范围很小,才是0--10,符合二分原理。
      3 二分出一个V,就用spfa求一次最短路,看看最短的长度与L大小关系,以此来二分。
      4 */
      5 #include<cmath>
      6 #include<iostream>
      7 using namespace std;
      8 #include<cstdio>
      9 #include<queue>
     10 #include<cstring>
     11 #define R 110
     12 int T,r,c;
     13 bool inque[R*R];
     14 char ditu[R][R];
     15 double L,z,y;
     16 double dist[R*R];
     17 int head[10010],bh=0,sta,endd,bhh[R][R];
     18 struct Edge{
     19     int v,last;
     20     double w;
     21 }edge[40005];
     22 int t=0;
     23 void input()
     24 {
     25     scanf("%lf%d%d
    ",&L,&r,&c);
     26     for(int i=1;i<=r;++i)
     27     {
     28         for(int j=1;j<=c;++j)
     29         {
     30             scanf("%c",&ditu[i][j]);
     31             if(ditu[i][j]==32) 
     32             {
     33                 bh++;
     34                 bhh[i][j]=bh;
     35             }
     36             if(ditu[i][j]=='S')bhh[i][j]=sta=++bh;
     37             if(ditu[i][j]=='E')bhh[i][j]=endd=++bh;
     38          } 
     39         scanf("
    ");
     40      } 
     41       
     42 }
     43 void add_edge(int i,int j)
     44 {
     45     if(i-1>0&&ditu[i-1][j]!='#') {++t;edge[t].v=bhh[i-1][j];edge[t].w=-1;edge[t].last=head[bhh[i][j]];head[bhh[i][j]]=t;}
     46     if(i<r&&ditu[i+1][j]!='#')   {++t;edge[t].v=bhh[i+1][j];edge[t].w=-1;edge[t].last=head[bhh[i][j]];head[bhh[i][j]]=t;}
     47     if(j-1>0&&ditu[i][j-1]!='#') {++t;edge[t].v=bhh[i][j-1];edge[t].w=1;edge[t].last=head[bhh[i][j]];head[bhh[i][j]]=t;}
     48     if(j<c&&ditu[i][j+1]!='#')   {++t;edge[t].v=bhh[i][j+1];edge[t].w=1;edge[t].last=head[bhh[i][j]];head[bhh[i][j]]=t;}
     49 }
     50 void build_tu()
     51 {
     52    for(int i=1;i<=r;++i)
     53      for(int j=1;j<=c;++j)
     54      if(ditu[i][j]!='#') 
     55      {
     56          add_edge(i,j);    
     57      }
     58 }
     59 double SPFA(double ww)
     60 {
     61     for(int i=1;i<=bh;++i)
     62       dist[i]=(1<<30)-1;
     63     dist[sta]=0;
     64     memset(inque,false,sizeof(inque));
     65     queue<int>Q;
     66     Q.push(sta);
     67     inque[sta]=true;
     68     while(!Q.empty())
     69     {
     70         int nowt=Q.front();
     71         Q.pop();
     72         inque[nowt]=false;
     73         for(int l=head[nowt];l;l=edge[l].last)
     74         {
     75             if(edge[l].w<0)
     76             {
     77                 if(dist[edge[l].v]>dist[nowt]+ww)
     78                 {
     79                     dist[edge[l].v]=dist[nowt]+ww;
     80                     if(!inque[edge[l].v])
     81                     {
     82                         inque[edge[l].v]=true;
     83                         Q.push(edge[l].v);
     84                     }
     85                 }
     86             }
     87             else {
     88                 if(dist[edge[l].v]>dist[nowt]+edge[l].w)
     89                 {
     90                     dist[edge[l].v]=dist[nowt]+edge[l].w;
     91                     if(!inque[edge[l].v])
     92                     {
     93                         inque[edge[l].v]=true;
     94                         Q.push(edge[l].v);
     95                     }
     96                 }
     97             }
     98         }
     99     }
    100     return dist[endd];
    101 }
    102 int main()
    103 {
    104     cin>>T;
    105     while(T--)
    106     {
    107       input();
    108       build_tu();
    109       z=0;y=10;
    110       while(z<=y)
    111       {
    112           double mid=(z+y)/2;
    113           double ans=SPFA(mid);
    114           if(ans>=L) y=mid-0.000001;/*注意这里要加0.000001,之前的二分加1,是为了去一个区间(int),但是现在是double,所以要+0
    115 .000001。*/
    116           else z=mid+0.000001;
    117       }
    118       printf("%0.5lf
    ",y);
    119     }
    120     
    121     return 0;
    122 }
  • 相关阅读:
    flask基础之jijia2模板使用基础(二)
    python之微信公众号开发(基本配置和校验)
    flask插件系列之SQLAlchemy基础使用
    python基础之常用的高阶函数
    服务器部署之nginx的配置
    python之gunicorn的配置
    python内置模块之unittest测试(五)
    python之celery使用详解一
    git服务器的简单搭建
    python模块分析之logging日志(四)
  • 原文地址:https://www.cnblogs.com/c1299401227/p/5954492.html
Copyright © 2020-2023  润新知