bzoj1295 [SCOI2009]最长距离

Description

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

Input

输入文件maxlength.in第一行包含三个整数,N M T。 接下来有N行,每行一个长度为M的字符串,'0'表示空格子,'1'表示该格子含有障碍物。

Output

输出文件maxlength.out包含一个浮点数,保留6位小数。

Sample Input

【输入样例一】
3 3 0
001
001
110
【输入样例二】
4 3 0
001
001
011
000
【输入样例三】
3 3 1
001
001
001

Sample Output

【输出样例一】
1.414214
【输出样例二】
3.605551
【输出样例三】
2.828427

HINT 

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

 

正解:$spfa$。

蜜汁脑抽了一回。。

如果移掉$t$个障碍以后两点可以连通,那么它们之间肯定存在一条路,使得障碍数$\leq t$。

然后我们对于每个点跑一遍最短路,计算一下最短路$\leq t$的点的距离,然后就没了。。

 

 1 #include <bits/stdc++.h>
 2 #define il inline
 3 #define RG register
 4 #define ll long long
 5 #define inf (1<<30)
 6 
 7 using namespace std;
 8 
 9 struct data{ int x,y; };
10 
11 queue<data> Q;
12 
13 const int d1[4]={1,0,-1,0};
14 const int d2[4]={0,1,0,-1};
15 
16 int dis[40][40],vis[40][40],g[40][40],n,m,t;
17 double ans;
18 
19 il int gi(){
20   RG int x=0,q=1; RG char ch=getchar();
21   while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
22   if (ch=='-') q=-1,ch=getchar();
23   while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
24   return q*x;
25 }
26 
27 il char gc(){
28   RG char ch=getchar();
29   while (ch!='0' && ch!='1') ch=getchar(); return ch;
30 }
31 
32 il void spfa(RG int sx,RG int sy){
33   for (RG int i=1;i<=n;++i)
34     for (RG int j=1;j<=m;++j) dis[i][j]=inf;
35   Q.push((data){sx,sy}),dis[sx][sy]=g[sx][sy],vis[sx][sy]=1;
36   while (!Q.empty()){
37     RG data now=Q.front(); Q.pop();
38     for (RG int i=0,x,y;i<4;++i){
39       x=now.x+d1[i],y=now.y+d2[i];
40       if (x<=0 || x>n || y<=0 || y>m) continue;
41       if (dis[x][y]>dis[now.x][now.y]+g[x][y]){
42     dis[x][y]=dis[now.x][now.y]+g[x][y];
43     if (!vis[x][y]) Q.push((data){x,y}),vis[x][y]=1;
44       }
45     }
46     vis[now.x][now.y]=0;
47   }
48   for (RG int i=1;i<=n;++i)
49     for (RG int j=1;j<=m;++j)
50       if (dis[i][j]<=t) ans=max(ans,sqrt((sx-i)*(sx-i)+(sy-j)*(sy-j)));
51   return;
52 }
53 
54 int main(){
55 #ifndef ONLINE_JUDGE
56   freopen("maxlength.in","r",stdin);
57   freopen("maxlength.out","w",stdout);
58 #endif
59   n=gi(),m=gi(),t=gi();
60   for (RG int i=1;i<=n;++i)
61     for (RG int j=1;j<=m;++j) g[i][j]=gc()-'0';
62   for (RG int i=1;i<=n;++i)
63     for (RG int j=1;j<=m;++j) spfa(i,j);
64   printf("%0.6lf\n",ans); return 0;
65 }

 

posted @ 2017-10-24 22:30  wfj_2048  阅读(168)  评论(0编辑  收藏  举报