您的位置:首页 > 编程语言 > Java开发

青云的机房组网方案(简单)-Java

2016-06-05 12:35 591 查看
青云现在要将 nnn 个机房连成一个互相连通的网络。工程师小王设计出一个方案:通过在 nnn 个机房之间铺设 n−1n-1n−1 条双向的光纤,将所有的机房连接。可以假设数据在两个机房之间的光纤传输需要 111 单位时间。每个机房 iii 有一个初始值 aia_ia​i​​,当两个机房的初始值之间互质时,我们认为这两个机房之间的传输性能是非常重要的。请帮小王计算出所有数值互质的机房对之间的传输时间之和。

输入格式

第一行输入一个正整数 nnn,第二行输入 nnn 个正整数 a1…ana_1…a_na​1​​…a​n​​,表示 nnn 个机房的初始值。

接下来输入 n−1n-1n−1 行,每行输入两个数 a,ba,ba,b,表示机房 aaa 和机房 bbb 之间有一条双向网络管道。

对于简单版本:n≤500,1≤ai≤501 \leq a_i \leq 501≤a​i​​≤50;;

对于中等版本:n≤10000n \leq 10000n≤10000, 1≤ai≤5001 \leq a_i \leq 5001≤a​i​​≤500;

对于困难版本:n≤100000n \leq 100000n≤100000,ai≤100000a_i \leq 100000a​i​​≤100000。

输出格式

输出一行,表示所有初始值互质的机房对的传输时间和。

样例输入

4

1 2 3 4

1 2

2 3

3 4

样例输出

8

提示信息

对于第一组样例,每一组初始值互质的机房对的传输时间如下:

(1,2:1

(1,3):2

(1,4):3

(2,3):1

(3,4):1

所以,所有初始值互质的机房对的传输时间和为 1+2+3+1+1=8。

import java.util.Scanner;

public class Main {

private static int n, u;
private static int inf = 999999999;
private static int[][] map;
private static int[][] count;
private static int sum=0;

public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
int[] data = new int
;
for (int i = 0; i < data.length; i++) {
data[i] = sc.nextInt();
}
count=new int[n-1]
;
map = new int

;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
map[i][j] = inf;
}
map[i][i] = 0;
}
for (int i = 1; i < n; i++) {
int p1 = sc.nextInt() - 1;
int p2 = sc.nextInt() - 1;
map[p1][p2] = 1;
map[p2][p1] = 1;
}
for (int i = 0; i < data.length-1 ; i++) {
dis(i);
}
for (int i = 0; i < data.length-1; i++) {
if (i+1<data.length) {
for (int j = i+1; j < data.length; j++) {
if(is_prime(data[i], data[j])==1 ){
sum+=count[i][j];
}
}
}
}
System.out.println(sum);
}
private static void dis(int star) {
// TODO Auto-generated method stub
int[] dis = new int
;
for (int i = 0; i < n; i++) {
dis[i] = map[star][i];// 取star号顶点到各个顶点的距离
}

// book数组初始化
int[] book = new int
;
book[star] = 1;

// dijkstra核心算法
/*
* 为什么是n-1 呢?
*
* 最短路径肯定是一个不包含回路的 简单路径,回路分为正权回路(回路权值之和为正) 和负权回路(回路权值之和为负)
* 如果最短路径中包含正权回路,那么去掉这个回路,一定可以得到更短的路径 。 如果路径中包含负权回路,那么肯定没有
* 最短路径,因为没多走一次负权回路,就可以得到更短的路径。 因此最路径肯定是一个不包含回路的简单路径,即最多包含
* n-1条路径,所以进行n-1次松弛就可以了
*
*/
for (int i = 0; i < n - 1; i++) {
int min = inf;
for (int j = 0; j < n; j++) {
if (book[j] == 0 && dis[j] < min) {
min = dis[j];
u = j;
}
}
book[u] = 1;
for (int v = 0; v < n; v++) {
if (map[u][v] < inf) {
if (dis[v] > dis[u] + map[u][v]) {// dis数组表示的是1号顶点到各个顶点的最短距离,
// 1号顶点到v的距离 与通过u顶点中转后
// 到v顶点的距离做对比,
dis[v] = dis[u] + map[u][v];
}
}
}
}
//      for (int i = 0; i < n; i++) {
//          System.out.print(dis[i] + "\t");
//      }
count[star]=dis;

}

private static int is_prime(int a, int b) {
// TODO Auto-generated method stub
if (a < b) {
int tmp = a;
a = b;
b = tmp;
}
int c;
while ((c = a % b) != 0) {
a = b;
b = c;
}
return b;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: