zoukankan      html  css  js  c++  java
  • 【BZOJ】【3007】拯救小云公主

    思路题


      我的naive的做法是二分答案+判定是否有路径可走……但是没有正确理解【走的方向任意】这句话……

      其实就是说想咋走咋走= =360°无死角乱走……

      所以其实是个平面上的问题……

      我们可以换个方向来考虑……二分一个答案,判断英雄走到/走不到公主那里,是不是就等价于,boss控制的区域连起来了使得英雄走不到公主那里了?(狼抓兔子的即视感)

      所以我们可以转化成从上边&左边,在boss之间走,使得走到下边&右边 路径上最大的一条边(边权代表着如果英雄从这两个boss之间经过,离两个boss最近的距离(所以就是$frac{dis(boss[i],boss[j])}{2}$))最小。

      这个好像不能SPFA?(明明是你蒻)……我WA40了……只能bellman-ford迭代了……

     1 /**************************************************************
     2     Problem: 3007
     3     User: Tunix
     4     Language: C++
     5     Result: Accepted
     6     Time:1176 ms
     7     Memory:72104 kb
     8 ****************************************************************/
     9  
    10 //Huce #3 A
    11 #include<cmath>
    12 #include<queue>
    13 #include<vector>
    14 #include<cstdio>
    15 #include<cstdlib>
    16 #include<cstring>
    17 #include<iostream>
    18 #include<algorithm>
    19 #define rep(i,n) for(int i=0;i<n;++i)
    20 #define F(i,j,n) for(int i=j;i<=n;++i)
    21 #define D(i,j,n) for(int i=j;i>=n;--i)
    22 using namespace std;
    23  
    24 int getint(){
    25     int v=0,sign=1; char ch=getchar();
    26     while(ch<'0'||ch>'9') {if (ch=='-') sign=-1; ch=getchar();}
    27     while(ch>='0'&&ch<='9') {v=v*10+ch-'0'; ch=getchar();}
    28     return v*sign;
    29 }
    30 typedef long long LL;
    31 const int N=3010,INF=~0u>>2;
    32 const double eps=1e-5;
    33 /*******************tamplate********************/
    34 struct Boss{
    35     int x,y;
    36     Boss(){}
    37     Boss(int x,int y):x(x),y(y){}
    38     void read(){scanf("%d%d",&x,&y);}
    39 }boss[N];
    40 double inf = 1 << 25,g[N][N],f[N];
    41 int n,row,line;
    42 double dis(Boss a,Boss b){
    43     double x,y;
    44     x=a.x-b.x; y=a.y-b.y;
    45     return sqrt(x*x+y*y);
    46 }
    47 void build(){
    48     F(i,1,n+4) F(j,1,n+4) g[i][j]=inf;
    49     F(i,1,n) F(j,i+1,n)
    50         g[i][j]=g[j][i]=dis(boss[i],boss[j])/2;
    51     F(i,1,n){
    52         g[n+1][i]=boss[i].y-1;
    53         g[n+2][i]=row-boss[i].x;
    54         g[i][n+3]=line-boss[i].y;
    55         g[i][n+4]=boss[i].x-1;
    56     }
    57 }
    58  
    59 bool vis[N];
    60 double solve(){
    61     memset(vis,0,sizeof vis);
    62     F(i,1,n+4) f[i]=inf;
    63     f[n+1]=f[n+2]=0;
    64     vis[n+1]=vis[n+2]=1;
    65     double mn; int l;
    66     while(1){
    67         mn=inf; l=-1;
    68         F(i,1,n+4) if (vis[i] && f[i]<mn){
    69             mn=f[i]; l=i;
    70         }
    71         if (l==-1) break;
    72         F(i,1,n+4)
    73             if (max(g[l][i],f[l])<f[i]){
    74                 f[i]=max(g[l][i],f[l]);
    75                 vis[i]=1;
    76             }
    77         vis[l]=0;
    78     }
    79     return min(f[n+3],f[n+4]);
    80 }
    81 int main(){
    82 #ifndef ONLINE_JUDGE
    83     freopen("input.txt","r",stdin);
    84 //  freopen("output.txt","w",stdout);
    85 #endif
    86     n=getint(); row=getint(); line=getint();
    87     F(i,1,n) boss[i].read();
    88     double ans=inf;
    89     F(i,1,n){
    90         ans=min(ans,dis(Boss(1,1),boss[i]));
    91         ans=min(ans,dis(Boss(row,line),boss[i]));
    92         //用起始位置和结束位置更新答案
    93     }
    94     build();
    95     ans=min(ans,solve());
    96     printf("%.2lf
    ",ans);
    97     return 0;
    98 }
    View Code

    UPD:果然是我spfa的姿势不对,终于A了,但是比迭代还要慢……我写的spfa就是shit QAQ

    ZYF:因为是邻接矩阵(完全图),边都是满的……

     1 /**************************************************************
     2     Problem: 3007
     3     User: Tunix
     4     Language: C++
     5     Result: Accepted
     6     Time:2172 ms
     7     Memory:72116 kb
     8 ****************************************************************/
     9  
    10 //Huce #3 A
    11 #include<cmath>
    12 #include<queue>
    13 #include<vector>
    14 #include<cstdio>
    15 #include<cstdlib>
    16 #include<cstring>
    17 #include<iostream>
    18 #include<algorithm>
    19 #define rep(i,n) for(int i=0;i<n;++i)
    20 #define F(i,j,n) for(int i=j;i<=n;++i)
    21 #define D(i,j,n) for(int i=j;i>=n;--i)
    22 using namespace std;
    23  
    24 int getint(){
    25     int v=0,sign=1; char ch=getchar();
    26     while(ch<'0'||ch>'9') {if (ch=='-') sign=-1; ch=getchar();}
    27     while(ch>='0'&&ch<='9') {v=v*10+ch-'0'; ch=getchar();}
    28     return v*sign;
    29 }
    30 typedef long long LL;
    31 const int N=3010,INF=~0u>>2;
    32 const double eps=1e-5;
    33 /*******************tamplate********************/
    34 struct Boss{
    35     int x,y;
    36     Boss(){}
    37     Boss(int x,int y):x(x),y(y){}
    38     void read(){scanf("%d%d",&x,&y);}
    39 }boss[N];
    40 double inf = 1 << 25,g[N][N],f[N];
    41 int n,row,line;
    42 double dis(Boss a,Boss b){
    43     double x,y;
    44     x=a.x-b.x; y=a.y-b.y;
    45     return sqrt(x*x+y*y);
    46 }
    47 void build(){
    48     F(i,1,n+4) F(j,1,n+4) g[i][j]=inf;
    49     F(i,1,n) F(j,i+1,n)
    50         g[i][j]=g[j][i]=dis(boss[i],boss[j])/2;
    51     F(i,1,n){
    52         g[n+1][i]=boss[i].y-1;
    53         g[n+2][i]=row-boss[i].x;
    54         g[i][n+3]=line-boss[i].y;
    55         g[i][n+4]=boss[i].x-1;
    56     }
    57 }
    58 int Q[N];
    59 bool inq[N];
    60 double solve(){
    61     F(i,1,n+4) f[i]=INF;
    62     f[n+1]=f[n+2]=0;
    63     int l=0,r=0;
    64     Q[r++]=n+1; inq[n+1]=1;
    65     Q[r++]=n+2; inq[n+2]=1;
    66     while(l!=r){
    67         int x=Q[l]; inq[x]=0;
    68         l=(l+1)%N;
    69         inq[x]=0;
    70         F(i,1,n+4)
    71             if (max(g[x][i],f[x])<f[i]){
    72                 f[i]=max(g[x][i],f[x]);
    73                 if (!inq[i]){
    74                     Q[r]=i;
    75                     r=(r+1)%N;
    76                     inq[i]=1;
    77                 }
    78             }
    79     }
    80     return min(f[n+3],f[n+4]);
    81 }
    82 int main(){
    83 #ifndef ONLINE_JUDGE
    84     freopen("input.txt","r",stdin);
    85 //  freopen("output.txt","w",stdout);
    86 #endif
    87     n=getint(); row=getint(); line=getint();
    88     F(i,1,n) boss[i].read();
    89     double ans=1e20;
    90     F(i,1,n){
    91         ans=min(ans,dis(Boss(1,1),boss[i]));
    92         ans=min(ans,dis(Boss(row,line),boss[i]));
    93         //ÓÃÆðʼλÖúͽáÊøλÖøüд𰸠
    94     }
    95     build();
    96     ans=min(ans,solve());
    97     printf("%.2lf
    ",ans);
    98     return 0;
    99 }
    View Code

    3007: 拯救小云公主

    Time Limit: 5 Sec  Memory Limit: 512 MB
    Submit: 71  Solved: 36
    [Submit][Status][Discuss]

    Description

        英雄又即将踏上拯救公主的道路……
        这次的拯救目标是——爱和正义的小云公主。
        英雄来到boss的洞穴门口,他一下子就懵了,因为面前不只是一只boss,而是上千只boss。当英雄意识到自己还是等级1的时候,他明白这就是一个不可能完成的任务。
        但他不死心,他在想,能不能避开boss去拯救公主呢,嘻嘻。
        Boss的洞穴可以看成一个矩形,英雄在左下角(1,1),公主在右上角(row,line)。英雄为了避开boss,当然是离boss距离越远越好了,所以英雄决定找一条路径使到距离boss的最短距离最远。
    Ps:英雄走的方向是任意的。
        你可以帮帮他吗?
        当英雄找到了美丽漂亮的小云公主,立刻就被boss包围了!!!英雄缓闭双眼,举手轻挥,白光一闪后使用了回城卷轴,回到了城堡,但只有小云公主回去了……因为英雄忘了进入回城的法阵了。
     

    Input

        第一行,输入三个整数,n表示boss的数目,row,line表示矩形的大小;
        接下来n行,每行分别两个整数表示boss的位置坐标。
     

    Output

        输出一个小数,表示英雄的路径离boss的最远距离,精确到小数点后两位。
     

    Sample Input

    1 3 3
    2 2

    输出样例1:
    1.00

    输入样例2:
    1 3 3
    3 1

    输出样例2:
    2.00

    Sample Output

     

    HINT

    100%数据,n<=3000;

    Source

    [Submit][Status][Discuss]
  • 相关阅读:
    Python实现机器人聊天
    node.js使用express框架进行文件上传
    nginx让所有的http地址重定向到https
    nginx配置https
    vscode源码编译运行打包使其由英文变为中文
    阿里云配置tomcat https
    springboot打成的jar包如何在Linux上持久运行
    wordpress数据表分析
    DevExpress Components16.2.6 Source Code 重编译教程
    DataGridView绑定泛型List时,利用BindingList来实现增删查改
  • 原文地址:https://www.cnblogs.com/Tunix/p/4440239.html
Copyright © 2011-2022 走看看