CCF—無線網路 Java
阿新 • • 發佈:2018-12-16
問題描述
目前在一個很大的平面房間裡有 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
一下程式碼只是考慮了新增一個點的時候,新增多餘一個點的情況沒有考慮 希望有大佬們可以指點一二。
import java.util.Arrays; import java.util.Scanner; public class Wireless { static Scanner sc; static int n,m,k,r; static int[][] edge; static Apoint[] point; static boolean[] isVisited; static int[] dist; static int[] len; static final int INF = Integer.MAX_VALUE; // 最大值 public static void main(String[] args) { sc = new Scanner(System.in); n=sc.nextInt(); //已經存在的無線網路的點 m=sc.nextInt(); //新增的無線網路的點 k=sc.nextInt(); //表示新增幾個點 r=sc.nextInt(); //最短可以聯絡的距離 point = new Apoint[n+1]; edge = new int[n+2][n+2]; dist = new int[n+2]; len = new int[m]; //儲存已經存在的點 for(int i =0;i<n;i++) { point[i] = new Apoint(i+1,sc.nextInt(),sc.nextInt()); } //新增一個網路點的情況 for(int k=0;k<m;k++) { point[n] = new Apoint(n+1,sc.nextInt(),sc.nextInt()); //每次重新初始化edge二維陣列 init(); for(int i=0;i<=n;i++) for(int j=0;j<=n;j++) if(point[i].num==point[j].num) { continue; } else if(((point[i].x-point[j].x)*(point[i].x-point[j].x)+(point[i].y-point[j].y)*(point[i].y-point[j].y))<=9) { edge[point[i].num][point[j].num]=1; edge[point[j].num][point[i].num]=1; } len[k]=Distras(2); } Arrays.sort(len); //System.out.print(len[0]+" "+len[1]+" "+len[2]); System.out.println(len[0]-1); } public static void init() { for(int i = 1 ; i <= n+1 ; i++) { for(int j = 1 ; j <= n+1 ; j++) { if(i == j) edge[i][j] = 0; else edge[i][j] = INF; } } } //利用締結斯塔拉演算法 算出單源最短距離 public static int Distras(int end) { isVisited = new boolean[n+2]; //初始化 for(int i = 1 ; i <=n+1 ; i++) { isVisited[i] = false; //表明頂點i的最短路徑還沒有獲取到 dist[i] = edge[1][i]; //表明起始點到頂點i的距離 } //對起始點進行初始化 isVisited[1] = true; dist[1] = 0; int k = 0; //遍歷n次 每一次都找到一個頂點的最短路徑 for(int i = 0 ; i < n ; i++) { int min = INF; for(int j = 1 ; j <= n+1 ; j++) { if(isVisited[j] == false && min > dist[j]) { min = dist[j]; k = j; } } isVisited[k] = true; //更新dist陣列 for(int j = 1 ; j <= n+1 ; j++) { int temp = (edge[k][j] == INF ? INF : (min + edge[k][j])); if(isVisited[j] == false && (temp < dist[j])) { dist[j] = temp; } } } return dist[2]; } } class Apoint{ public int num; //點的編號 public int x; //點的x軸的位置 public int y; //點的y軸的位置 public Apoint(int num, int x, int y) { this.num = num; this.x = x; this.y = y; } }