欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

无线网络

程序员文章站 2022-06-06 12:10:50
...

无线网络

问题

问题描述

试题编号: 201403-4
试题名称: 无线网络
时间限制: 1.0s
内存限制: 256.0MB
问题描述:

问题描述

  目前在一个很大的平面房间里有 n 个无线路由器,每个无线路由器都固定在某个点上。任何两个无线路由器只要距离不超过 r 就能互相建立网络连接。
  除此以外,另有 m 个可以摆放无线路由器的位置。你可以在这些位置中选择至多 k 个增设新的路由器。
  你的目标是使得第 1 个路由器和第 2 个路由器之间的网络连接经过尽量少的中转路由器。请问在最优方案下中转路由器的最少个数是多少?

输入格式

  第一行包含四个正整数 n,m,k,r。(2 ≤ n ≤ 100,1 ≤ k ≤ m ≤ 100, 1 ≤ r ≤ 108)。
  接下来 n 行,每行包含两个整数 xi 和 yi,表示一个已经放置好的无线 路由器在 (xi, yi) 点处。输入数据保证第 1 和第 2 个路由器在仅有这 n 个路由器的情况下已经可以互相连接(经过一系列的中转路由器)。
  接下来 m 行,每行包含两个整数 xi 和 yi,表示 (xi, yi) 点处可以增设 一个路由器。
  输入中所有的坐标的绝对值不超过 108,保证输入中的坐标各不相同。

输出格式

  输出只有一个数,即在指定的位置中增设 k 个路由器后,从第 1 个路 由器到第 2 个路由器最少经过的中转路由器的个数。

样例输入

5 3 1 3
0 0
5 5
0 3
0 5
3 5
3 3
4 4
3 0

样例输出

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;
}