题目:
https://pintia.cn/problem-sets/1268384564738605056/problems/1284061680920891392
题解:https://blog.csdn.net/tuzigg123/article/details/46897871
代码:
/*2015.7.15cyq*/ #include <iostream> #include <vector> #include <math.h> #include <queue> #include <fstream> #include <map> using namespace std; //ifstream fin("case1.txt"); //#define cin fin struct point{ float x; float y; bool canEscape; int prePoint;//BFS时的前驱结点,便于从终点回溯到起点,用于输出路径 }; int main(){ int N,D; cin>>N>>D; if(D>=50){ cout<<"1"<<endl; return 0; } vector<point> vexs(N); vector<vector<bool> > edges(N,vector<bool>(N,false)); for(int i=0;i<N;i++){//鳄鱼序号为0到N-1 cin>>vexs[i].x>>vexs[i].y; if(fabs(vexs[i].x)+D>=50||fabs(vexs[i].y)+D>=50){ vexs[i].canEscape=true; //标记能一步跳到岸边的点 }else vexs[i].canEscape=false; } for(int i=0;i<N;i++){ for(int j=i+1;j<N;j++){ float dx=vexs[i].x-vexs[j].x; float dy=vexs[i].y-vexs[j].y; if(dx*dx+dy*dy<=D*D){//标记能够两两连通的点 edges[i][j]=true; edges[j][i]=true; } } } //BFS queue<int> cur,next; vector<int> visited(N,false); map<float,int> firstJump; for(int i=0;i<N;i++){ float tmp=vexs[i].x*vexs[i].x+vexs[i].y*vexs[i].y; if(tmp<=(D+7.5)*(D+7.5)){ firstJump[tmp]=i; //用map对第一跳的点的距离进行自动升序排序 vexs[i].prePoint=-1;//前驱结点为-1,表示原点 } } for(auto it=firstJump.begin();it!=firstJump.end();++it){ cur.push((*it).second);//第一跳能跳到的点从小到大入队 visited[(*it).second]=true; } bool find=false; vector<int> result; while(!cur.empty()){ if(find) break; while(!cur.empty()){ int root=cur.front(); cur.pop(); if(vexs[root].canEscape){ while(vexs[root].prePoint!=-1){ result.push_back(root); root=vexs[root].prePoint; } result.push_back(root); find=true; break; } for(int i=0;i<N;i++){ if(edges[root][i]&&!visited[i]){ next.push(i); visited[i]=true; vexs[i].prePoint=root;//每个结点入队时都要记录其前驱结点 } } } swap(cur,next); } int n=result.size(); if(n==0) cout<<"0"<<endl; else{ cout<<n+1<<endl; for(int i=n-1;i>=0;i--) cout<<vexs[result[i]].x<<" "<<vexs[result[i]].y<<endl; } return 0; }