CCF201403-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

#include<iostream>
#include<queue>
#include<cstring>
#include<cmath>
#include<fstream>
#define N 210
#define INF 100000001
typedef long long LL ;
using namespace std;

//無線路由器:橫縱座標 
struct R{
    int x;
    int y;
};

struct P_D{
    int dest;       //目的結點 
    int add;        //通過的增設結點的數量 
};

int n;      //路由器個數
int m;      //可擺放路由器的位置
int k;      //可新增的路由器個數
int r;      //可建立連接的距離
R ruter[N];         //已有的和可增設的路由器 
int d[N][N];        //d[i][j]表示從起點開始經過增設的j個路由器到達i的最短路徑
bool vis[N][N];     //vis[i][j]表示是否可以從起點經過增設的j個路由器到達i 
bool Map[N][N];     //鄰接矩陣 

//  使用spfa算法求最短路徑
void spfa(){
    queue <P_D> Q;      //保存結點的隊列
    P_D s, temp;        //源點,目的結點 
    s.dest = 0;
    s.add = 0;
    Q.push( s );        //初始時隊列中只有起始點

    memset( d, INF, sizeof(d) );
    memset( vis, 0, sizeof(vis) );
    d[0][0] = 0;
    vis[0][0] = 1; 

    while( !Q.empty() ){
        s = Q.front();
        Q.pop();
        vis[s.dest][s.add] = 0;

        for( int i = 0; i < n+m; i++ ){
            if( Map[s.dest][i] ){
                temp.dest = i;
                temp.add = s.add;
                if( i >= n ){
                    temp.add++;
                }
                if( temp.add <= k && d[temp.dest][temp.add] > d[s.dest][s.add]+1 ){
                    d[temp.dest][temp.add] = d[s.dest][s.add]+1;
                    if( !vis[temp.dest][temp.add] ){
                        vis[temp.dest][temp.add] = 1;
                        Q.push( temp );
                    }
                }
            }
        } 
    } 

    int count = INF;
    for( int i = 0; i <= k; i++ ){
        count = min( count, d[1][i] );
    }
    cout << count - 1;
} 

int main(){ 
//  讀入數據 
//  ifstream fin("00.txt", ios::in);
//  fin >> n >> m >> k >> r;    
    cin >> n >> m >> k >> r;    
    for( int i = 0; i < n+m; i++ ){
//      fin >> ruter[i].x >> ruter[i].y; 
        cin >> ruter[i].x >> ruter[i].y; 
    }

//  初始化無向圖鄰接矩陣,無邊置0 ,有邊置1
    memset( Map, 0, sizeof(Map) );
    for( int i = 0; i < n+m; i++ ){
        for( int j = i+1; j < n+m; j++ ){
            if( (LL)pow((ruter[i].x - ruter[j].x), 2) + (LL)pow((ruter[i].y - ruter[j].y), 2) <= (LL)r*r ){
                Map[i][j] = Map[j][i] = 1; 
            } 
        }
    }

//  使用spfa算法求最短路徑
    spfa(); 

    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章