bzoj1295[SCOI2009]最长距离
题意:
N*M块地,如果两块地都没有障碍物,则互相可达。如果两块地互相可达(可经过其他地)则它们之间的距离为它们中心点的欧几里得距离,求如果能移走不大于T个障碍物,土地间的最大距离。N,M≤30
题解:
把经过一个障碍物视为边长度为1,求出每两个点之间要跨越的边长度,如果长度小于等于T,就将其欧几里得距离和答案比较。
代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <queue> 5 #include <cmath> 6 #include <cctype> 7 #define maxn 100 8 #define inc(i,j,k) for(int i=j;i<=k;i++) 9 using namespace std; 10 11 12 int map[maxn][maxn],n,m,k; double mx; 13 bool vis[maxn][maxn],inq[maxn][maxn]; int d[maxn][maxn]; 14 struct qn{int x,y;}; queue <qn> q; 15 void spfa(int sx,int sy){ 16 while(!q.empty())q.pop(); q.push((qn){sx,sy}); memset(d,-1,sizeof(d)); memset(inq,0,sizeof(inq)); 17 memset(vis,0,sizeof(vis)); d[sx][sy]=map[sx][sy]; inq[sx][sy]=1; 18 while(!q.empty()){ 19 qn x=q.front(); q.pop(); inq[x.x][x.y]=0; 20 if(x.x!=1&&(d[x.x-1][x.y]==-1||d[x.x-1][x.y]>d[x.x][x.y]+map[x.x-1][x.y])){ 21 d[x.x-1][x.y]=d[x.x][x.y]+map[x.x-1][x.y]; 22 if(!inq[x.x-1][x.y])inq[x.x-1][x.y]=1,q.push((qn){x.x-1,x.y}); 23 } 24 if(x.y!=1&&(d[x.x][x.y-1]==-1||d[x.x][x.y-1]>d[x.x][x.y]+map[x.x][x.y-1])){ 25 d[x.x][x.y-1]=d[x.x][x.y]+map[x.x][x.y-1]; 26 if(!inq[x.x][x.y-1])inq[x.x][x.y-1]=1,q.push((qn){x.x,x.y-1}); 27 } 28 if(x.x!=n&&(d[x.x+1][x.y]==-1||d[x.x+1][x.y]>d[x.x][x.y]+map[x.x+1][x.y])){ 29 d[x.x+1][x.y]=d[x.x][x.y]+map[x.x+1][x.y]; 30 if(!inq[x.x+1][x.y])inq[x.x+1][x.y]=1,q.push((qn){x.x+1,x.y}); 31 } 32 if(x.y!=m&&(d[x.x][x.y+1]==-1||d[x.x][x.y+1]>d[x.x][x.y]+map[x.x][x.y+1])){ 33 d[x.x][x.y+1]=d[x.x][x.y]+map[x.x][x.y+1]; 34 if(!inq[x.x][x.y+1])inq[x.x][x.y+1]=1,q.push((qn){x.x,x.y+1}); 35 } 36 } 37 inc(i,1,n)inc(j,1,m)if(d[i][j]<=k)vis[i][j]=1; 38 } 39 int main(){ 40 scanf("%d%d%d",&n,&m,&k); char c; 41 inc(i,1,n)inc(j,1,m){ 42 while(!isdigit(c=getchar())); map[i][j]=c-'0'; 43 } 44 inc(i,1,n)inc(j,1,m){ 45 spfa(i,j); inc(i0,1,n)inc(j0,1,m)if(vis[i0][j0])mx=max(mx,sqrt((i0-i)*(i0-i)+(j0-j)*(j0-j))); 46 } 47 printf("%.6lf",mx); return 0; 48 }
20160602