最长距离
[SCOI2009]最长距离
https://ac.nowcoder.com/acm/problem/20270
分析
首先亮瞎我狗眼的便是这个阔怕的数据范围
所以,这意味着我们直接暴力是没有问题的
所以我们直接枚举开始点
BFS+优先队列处理最短路
然后枚举另一个点
判断两人之间的最小移动障碍物个数是否Limit
即可
时间复杂度:
代码
//P4162 #include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <queue> #include <cmath> #define LL long long #define Cl(X,Y) memset((X),(Y),sizeof(X)) #define FOR(i,A,B) for(int i=A;i<=B;i++) #define BOR(i,A,B) for(int i=A;i>=B;i--) #define Lowbit(X) (X & (-X)) #define Skip cout<<endl; #define INF 0x3f3f3f3f #define Rson (X<<1|1) #define Lson (X<<1) using namespace std; const int MaxN=50; int Row,Line,Limit; char Map[MaxN][MaxN]; int Dist[MaxN][MaxN]; int Dx[5]={0,1,0,-1,0},Dy[5]={0,0,1,0,-1}; bool Vis[MaxN][MaxN]; struct Node { int first,second; friend bool operator < (Node A,Node B) { return Dist[A.first][A.second]>Dist[B.first][B.second]; } }; priority_queue<Node>Mine; double Ans; inline void File() { freopen(".in","r",stdin); freopen(".out","w",stdout); } inline void BFS(int X,int Y) { while(!Mine.empty()) Mine.pop(); Mine.push(Node{X,Y}); Vis[X][Y]=true; while(!Mine.empty()) { Node New=Mine.top(); Mine.pop(); for(int i=1;i<=4;i++) { int Nx=New.first+Dx[i],Ny=New.second+Dy[i]; if(Vis[Nx][Ny] || Nx>Row || Nx<1 || Ny>Line || Ny<1) continue; Dist[Nx][Ny]=Dist[New.first][New.second]+(Map[Nx][Ny]=='1'); Vis[Nx][Ny]=true; Mine.push(Node{Nx,Ny}); } } } int main() { // File(); // ios::sync_with_stdio(false); cin>>Row>>Line>>Limit; FOR(i,1,Row) scanf("%s",Map[i]+1); FOR(i,1,Row) FOR(j,1,Line) { Cl(Dist,0x3f); Cl(Vis,false); if(Map[i][j]=='0') Dist[i][j]=0; else Dist[i][j]=1; BFS(i,j); // FOR(k,1,Row) { FOR(p,1,Line) cout<<Dist[k][p]<<" "; Skip; } FOR(k,1,Row) FOR(p,1,Line) { if(Dist[k][p]>Limit) continue; Ans=max(Ans,sqrt(1.0*(k-i)*(k-i)+1.0*(p-j)*(p-j))); } } printf("%.6f\n",Ans); // fclose(stdin); // fclose(stdout); system("pause"); return 0; }