windy有一塊矩形土地,被分爲 NM 塊 11 的小格子。 有的格子含有障礙物。 若是從格子A能夠走到格子B,那麼兩個格子的距離就爲兩個格子中心的歐幾里德距離。 若是從格子A不能夠走到格子B,就沒有距離。 若是格子X和格子Y有公共邊,而且X和Y均不含有障礙物,就能夠從X走到Y。 若是windy能夠移走T塊障礙物,求全部格子間的最大距離。 保證移走T塊障礙物之後,至少有一個格子不含有障礙物。node
輸入格式:ios
第一行包含三個整數,N M T。 接下來有N行,每行一個長度爲M的字符串,'0'表示空格子,'1'表示該格子含有障礙物。spa
輸出格式:code
包含一個浮點數,保留6位小數。blog
輸入樣例#1: 複製ci
3 3 0
001
001
110字符串
輸出樣例#1: 複製get
1.414214string
輸入樣例#2: 複製it
4 3 0
001
001
011
000
輸出樣例#2: 複製
3.605551
輸入樣例#3: 複製
3 3 1
001
001
001
Sample Output
輸出樣例#3: 複製
2.828427
20%的數據,知足 1 <= N,M <= 30 ; 0 <= T <= 0 。
40%的數據,知足 1 <= N,M <= 30 ; 0 <= T <= 2 。
100%的數據,知足 1 <= N,M <= 30 ; 0 <= T <= 30 。
數據範圍30,30,只有900個點,跑900次\(dijkstra\),複雜度\(n^2logn\),這裏跑的最短路跑的是一個點到另外一個點所至少須要走的障礙數,貌似能過,再暴力枚舉兩個點\(n^2\)判斷能不能到達,就這樣了。
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<cmath> using namespace std; struct node { int to,next,w; }a[5010000]; typedef pair<int,int> pr; priority_queue<pr,vector<pr>,greater<pr> >q; int len,last[1010010],vis[1010],d[1001][1001],mp[1000][1000],n,m,t; int ar[]={0,0,1,-1}; int br[]={1,-1,0,0}; void add(int a1,int a2,int a3) { a[++len].to=a2; a[len].w=a3; a[len].next=last[a1]; last[a1]=len; } int real(int x,int y) { return (x-1)*m+y; } void dijkstra(int s) { memset(vis,0,sizeof(vis)); d[s][s]=0;q.push((pr){0,s}); while(!q.empty()) { int k=q.top().second;q.pop(); if(vis[k]) continue; vis[k]=1; for(int i=last[k];i;i=a[i].next) { int to=a[i].to; if(d[s][to]>d[s][k]+a[i].w) { d[s][to]=d[s][k]+a[i].w; if(!vis[to]) q.push((pr){d[s][to],to}); } } } } double dis(int i,int j,int x,int y) { return sqrt((i-x)*(i-x)+(j-y)*(j-y)); } int main() { char s[50]; memset(d,0x3f,sizeof(d)); cin>>n>>m>>t; for(int i=1;i<=n;i++) { scanf("%s",s+1); for(int j=1;j<=m;j++) if(s[j]=='1') mp[i][j]=1; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { for(int k=0;k<=3;k++) { int x=i+ar[k],y=j+br[k]; if(x==0||y==0||x==n+1||y==m+1) continue; add(real(i,j),real(x,y),mp[x][y]); } } double ans=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) dijkstra(real(i,j)); // cout<<d[8][1]<<endl; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) for(int x=1;x<=n;x++) for(int y=1;y<=m;y++) { int p1=real(i,j),p2=real(x,y); if(mp[i][j]) continue; if(d[p1][p2]<=t) { double pp=dis(i,j,x,y); if(ans<pp) ans=pp; } } printf("%.6lf",ans); }