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
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
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 }