1. 程式人生 > >bzoj1295:[SCOI2009]最長距離

bzoj1295:[SCOI2009]最長距離

描述 maxlength scoi2009 () zoj struct 並且 sample pop

題目描述

windy有一塊矩形土地,被分為 N*M 塊 1*1 的小格子。 有的格子含有障礙物。 如果從格子A可以走到格子B,那麽兩個格子的距離就為兩個格子中心的歐幾裏德距離。 如果從格子A不可以走到格子B,就沒有距離。 如果格子X和格子Y有公共邊,並且X和Y均不含有障礙物,就可以從X走到Y。 如果windy可以移走T塊障礙物,求所有格子間的最大距離。 保證移走T塊障礙物以後,至少有一個格子不含有障礙物。

輸入

輸入文件maxlength.in第一行包含三個整數,N M T。 接下來有N行,每行一個長度為M的字符串,‘0‘表示空格子,‘1‘表示該格子含有障礙物。

輸出

輸出文件maxlength.out包含一個浮點數,保留6位小數。

樣例輸入

【輸入樣例一】
3 3 0
001
001
110


【輸入樣例二】
4 3 0
001
001
011
000


【輸入樣例三】
3 3 1
001
001
001

樣例輸出

【輸出樣例一】
1.414214

【輸出樣例二】
3.605551

【輸出樣例三】
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 。

題解 數據範圍很小,考慮以每一個點為起點跑spfa,dis[i]記錄i點到該點的最小障礙物,然後判斷能否將這些障礙物刪除,更新最大距離。
  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<queue>
  5 #include<cmath>
  6 #define maxn 35
  7 #define inf 1<<29
  8 using namespace std;
  9 queue<int> q;
 10 int dx[5]={0,0,1,-1},dy[5]={1,-1,0,0};
 11 int n,m,t,tot,a[maxn*maxn],head[maxn*maxn],vis[maxn*maxn],d[maxn*maxn],ecnt;
12 double ans; 13 char str[35]; 14 struct edge{ 15 int u,v,next; 16 }E[maxn*maxn*4]; 17 void addedge(int u,int v) 18 { 19 E[++ecnt].u=u; 20 E[ecnt].v=v; 21 E[ecnt].next=head[u]; 22 head[u]=ecnt; 23 } 24 int cal(int x,int y){return m*(x-1)+y;} 25 bool ok(int x,int y) 26 { 27 if(x<=0||y<=0||x>n||y>m)return false; 28 return true; 29 } 30 void spfa(int x) 31 { 32 for(int i=1 ; i<=tot; ++i) 33 { 34 d[i]=inf; 35 vis[i]=0; 36 } 37 d[x]=a[x]; 38 vis[x]=1; 39 q.push(x); 40 while(!q.empty()) 41 { 42 int dd=q.front();q.pop(); 43 vis[dd]=0; 44 for(int i=head[dd] ; i ; i=E[i].next ) 45 { 46 int v=E[i].v; 47 if(d[v]>d[dd]+a[v]) 48 { 49 d[v]=d[dd]+a[v]; 50 if(!vis[v]) 51 { 52 vis[v]=1; 53 q.push(v); 54 } 55 } 56 } 57 } 58 } 59 void search(int x,int y,int xx,int yy) 60 { 61 int tmp=cal(xx,yy); 62 if(d[tmp]>t)return ; 63 ans=max(ans,sqrt((xx-x)*(xx-x)+(yy-y)*(yy-y))); 64 } 65 int main() 66 { 67 scanf("%d%d%d",&n,&m,&t); 68 tot=n*m; 69 for(int i=1 ; i<=n ; ++i ) 70 { 71 scanf("%s",str); 72 for(int j=0;j<m;++j) 73 { 74 int k=cal(i,j+1); 75 a[k]=str[j]-0; 76 } 77 } 78 for(int i=1 ; i<=n ; ++i ) 79 for(int j=1 ; j<=m ; ++j) 80 { 81 int tmp=cal(i,j); 82 for(int k=0;k<4;++k) 83 { 84 int x=i+dx[k],y=j+dy[k]; 85 if(ok(x,y))addedge(tmp,cal(x,y)); 86 } 87 } 88 for(int i=1 ; i<=n ; ++i ) 89 for(int j=1 ; j<=m ; ++j ) 90 { 91 int tmp=cal(i,j); 92 if(a[tmp]&&!t)continue; 93 spfa(tmp); 94 for(int k=1 ; k<=n ; ++k) 95 for(int p=1 ; p<=m ; ++p) 96 search(i,j,k,p); 97 } 98 printf("%.6lf",ans); 99 return 0; 100 }

bzoj1295:[SCOI2009]最長距離