无线网络
无线网络
问题
问题描述
试题编号: | 201403-4 |
试题名称: | 无线网络 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: |
问题描述 目前在一个很大的平面房间里有 n 个无线路由器,每个无线路由器都固定在某个点上。任何两个无线路由器只要距离不超过 r 就能互相建立网络连接。 输入格式 第一行包含四个正整数 n,m,k,r。(2 ≤ n ≤ 100,1 ≤ k ≤ m ≤ 100, 1 ≤ r ≤ 108)。 输出格式 输出只有一个数,即在指定的位置中增设 k 个路由器后,从第 1 个路 由器到第 2 个路由器最少经过的中转路由器的个数。 样例输入 5 3 1 3 样例输出 2 |
解题思路
开始接触此题时不知道从何处下手,画了平面图以后感觉是最短路径的求解问题,果不其然。当每一个点可以连接到时,可以组成一个图,此题的求解就变成了DAG的最短路径求解问题,使用BFS。
分析此题,因为在放置的新加入路由最多是k个,那么我们的节点应该记录已经放置的路由kcount的个数,如果遍历某个节点here时,已经放置了k个路由器,那么只能在前n个路由器中选择点进行存储转发,如果放置的kcount<k,那么可以在所有满足距离的点跳转,如果到了nodes[i] i>m的情况,那么我们就要加入一个路由器,此时点there.kcount 需要在here的基础上+1。到达终点以后我们结束遍历,返回step-1即可。
注意:由于r达到10^8所以我们需要使用long long 来表示点和距离。
实现代码
#include <iostream>
#include <algorithm>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#define rep(i,s,e) for(int i = s;i<e;i++)
using namespace std;
const int maxSize = 300;
typedef long long ll;
int vis[maxSize];
struct Point{
ll x;
ll y;
}points[maxSize];
struct Node{
Point point;
ll step,kcount;
};
ll n ,m,k,r;
bool judge(Point p1 ,Point p2){
return (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)<=r*r;
}
int bfs(){
int s = 0;
int e = 1;
memset(vis,0,maxSize);
vis[s] = 1;
Node nStart,nEnd;
nStart.kcount = 0;
nStart.step = 0;
nStart.point = points[0];
nEnd.point = points[1];
queue<Node> q;
q.push(nStart);
while(!q.empty()){
Node here = q.front();
q.pop();
if(here.point.x==nEnd.point.x&&here.point.y==nEnd.point.y){
return here.step-1;
}
int pMax = n;
if(here.kcount!=k){
pMax = m+n;
}
rep(i,0,pMax){
Node there;
there.point = points[i];
//判断是否访问
if(vis[i]){
continue;
}
//判断是否连接
if(!judge(there.point,here.point)){
continue;
}
vis[i] = 1;
there.step = here.step+1;
there.kcount = here.kcount;
if(i>=n){
there.kcount = here.kcount+1;
}
q.push(there);
}
}
}
int main(){
cin>>n>>m>>k>>r;
rep(i,0,n+m){
cin>>points[i].x>>points[i].y;
}
cout<<bfs()<<endl;
}