码迷,mamicode.com
首页 > 其他好文 > 详细

【BZOJ】【3007】拯救小云公主

时间:2015-04-20 00:08:30      阅读:361      评论:0      收藏:0      [点我收藏+]

标签:

思路题


  我的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\n",ans);
97     return 0;
98 }
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]

【BZOJ】【3007】拯救小云公主

标签:

原文地址:http://www.cnblogs.com/Tunix/p/4440239.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!