201403-4
#include <iostream> #include <cstring> #include <queue> //1.读准题意,是问第一个到第二个之间的距离 //2.注意范围,稍微大大一点的数尽量用long long //3.采用广度搜索,可以实现找到最短路径 //4.该题的关键在于引入kcount来表示已占用的点数和step来记录路径,实现在广度搜索的过程中,淘汰不合适的方案,达到相应搜索的目的 using namespace std; const int MAXN = 200; struct { long long x, y; } coord[MAXN+5]; struct status { long long x, y; int step, kcount; }; bool visited[MAXN+5]; int bfs(int n, int m, int k, int begin, int end, long long r) { int max; // 变量初始化 memset(visited, false, sizeof(visited)); // 设置根结点 status start, front, v; start.x = coord[begin].x; start.y = coord[begin].y; start.step = 0; start.kcount = 0; queue<status> q; q.push(start); // 设置根结点为已经访问过 visited[begin] = true; while(!q.empty()) { front = q.front(); q.pop(); // 到达终点则结束 if(front.x == coord[end].x && front.y == coord[end].y) return front.step - 1; // 搜索可以连接的路由器 if(front.kcount == k) max = n; else max = n + m; for(int i=0; i<max; i++) { // 访问过的坐标则跳过 if(visited[i]) continue; // 判定下一个路由器的坐标是否在半径r之内, 不在半径之内则跳过,在半径之内则继续搜索 if((front.x - coord[i].x) * (front.x - coord[i].x) + (front.y - coord[i].y) * (front.y - coord[i].y) > r * r) continue; else { // 第i个路由器设为已经访问过 visited[i] = true; // 计算步数,并且将第i个路由器加入队列 v.x = coord[i].x; v.y = coord[i].y; v.step = front.step + 1; if(i >= n) v.kcount = front.kcount + 1; else v.kcount = front.kcount; q.push(v); } } } return 0; } int main() { int n, m, k; long long r; // 输入数据 cin >> n >> m >> k >> r; for(int i=0; i<n+m; i++) // n个路由器的位置+可以增设的m个路由器的位置 cin >> coord[i].x >> coord[i].y; // 输出结果 cout << bfs(n, m, k, 0, 1, r) << endl; return 0; }
201403-4 |