zoukankan      html  css  js  c++  java
  • CCF CSP 201403-4 无线网络

    CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址

    CCF CSP 201403-4 无线网络

    问题描述

      目前在一个很大的平面房间里有 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

    解析

    路由器构成了一个图,如果两个路由器的距离小于r则存在边。
    求解的是最短路径。图所有边的权重均为1,因此可以用广度优先搜索解决。
    搜索的时候需要记录路径上所经过的增设路由器的个数,并确保不会超过k。
    使用广度优先搜索的层次遍历,可以方便地得到第1个路由器与第2个路由器之间的距离。

    代码

    C++

    #include <cstdio>
    #include <cmath>
    #include <queue>
    #include <vector>
    #define MAXN 210
    using namespace std;
    
    int N, M, K, R;
    bool graph[MAXN][MAXN];
    int pos[MAXN][2];
    
    bool inRange(int a, int b, int R) {
        return sqrt(pow(pos[a][0]-pos[b][0],2)+pow(pos[a][1]-pos[b][1],2))<=R;
    }
    
    int bfs(int s, int t) {
        vector<bool> visited(M+N);
        queue<pair<int,int> > q;
        q.push(make_pair(s,0));
        int len = 1, newLen, level = 1;
        while(len>0) {
            newLen = 0;
            for(int l=0; l<len; l++) {
                pair<int,int> f = q.front();
                if(f.first == t) return level-2;
                q.pop();
                for(int i=0; i<N; i++) {
                    if(graph[f.first][i] && !visited[i]) {
                        q.push(make_pair(i,f.second));
                        visited[i] = true;
                        newLen++;
                    }
                }
                for(int i=N; i<N+M; i++) {
                    if(graph[f.first][i] && !visited[i] && f.second<K) {
                        q.push(make_pair(i,f.second+1));
                        visited[i] = true;
                        newLen++;
                    }
                }
            }
            len = newLen;
            level++;
        }
        return -1;
    }
    
    int main() {
        scanf("%d%d%d%d", &N, &M, &K, &R);
        for(int i=0; i<N+M; i++) {
            scanf("%d%d", &pos[i][0], &pos[i][1]);
        }
        for(int i=0; i<N+M; i++) {
            for(int j=i+1; j<N+M; j++) {
                graph[i][j] = graph[j][i] = inRange(i, j, R);
            }
        }
        printf("%d", bfs(0, 1));
    }
  • 相关阅读:
    falsk 自定义中间件
    练习题
    4.12 作业题
    测试笔试题2
    测试笔试题
    简答题
    单选题
    普华和诚测试笔试试题
    缺陷报告
    测试用例点
  • 原文地址:https://www.cnblogs.com/meelo/p/7677599.html
Copyright © 2011-2022 走看看