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 ≤ 10 8)。
  接下來 n 行,每行包含兩個整數 x i 和 y i,表示一個已經放置好的無線 路由器在 (x i, y i) 點處。輸入數據保證第 1 和第 2 個路由器在僅有這 n 個路由器的情況下已經可以互相連接(經過一系列的中轉路由器)。
  接下來 m 行,每行包含兩個整數 x i 和 y i,表示 (x i, y i) 點處可以增設 一個路由器。
  輸入中所有的坐標的絕對值不超過 10 8,保證輸入中的坐標各不相同。

輸出格式

  輸出只有一個數,即在指定的位置中增設 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));
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM