最小生成树练习

来源:互联网 发布:录像监控软件 编辑:程序博客网 时间:2024/06/05 01:06

这是水题9

 There are N (2<=N<=600) cities,each has a value of happiness,we consider two cities A and B whose value of happiness are VA and VB,if VA is a prime number,or VB is a prime number or (VA+VB) is a prime number,then they can be connected.What's more,the cost to connecte two cities is Min(Min(VA , VB),|VA-VB|). 
Now we want to connecte all the cities together,and make the cost minimal.

Input

The first will contain a integer t,followed by t cases. 
Each case begin with a integer N,then N integer Vi(0<=Vi<=1000000).

Output

If the all cities can be connected together,output the minimal cost,otherwise output "-1";

Sample Input

2

5

1

2

3

4

5

 

4

4

4

4

4

Sample Output

4

-1

 

题意概括:

n个城市,每个城市都有一个幸福值,只有当两座城市的幸福值中有一个是素数或者这两个幸福值的和是素数的时候才可以连接。两座城市之间的权值是这两座城市的幸福值和他们差的绝对值,这三个值中最小的,输出将所有城市连接在一起最小需要的权值

解题分析:

这题最重要的就是数据的处理,只要数据处理完套用Kurskal模板就可以了。我的数据处理是将所有城市的幸福值存到一个数组中,再用一个book[]数组标记他们哪个是素数,是就记为1,不是记为0。

for(i = 1; i <= n; i++){//数据处理      for(j = i+1; j <= n; j++){           if(book[i] || book[j] || prime(c[i]+c[j])){                 stu[t].u = i;                 stu[t].v = j;                 stu[t].w = min(min(c[i], c[j]), abs(c[i]-c[j]));                 t++;           }      }}

代码:

#include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>using namespace std;#define N 610struct edge{    int u, v, w;}stu[N*N];int f[N];int prime(int n){    int k, i;    if(n == 1)        return 0;    k = (int)sqrt(n);    for(i = 2; i <= k; i++)        if(n % i == 0)            return 0;    return 1;}int cmp(edge a, edge b){    return a.w < b.w;}int getf(int v){    if(f[v] == v)        return v;    f[v] = getf(f[v]);    return f[v];}int Merge(int u, int v){    int t1, t2;    t1 = getf(u);    t2 = getf(v);    if(t1 != t2){        f[t2] = t1;        return 1;    }    return 0;}int Kruskal(int n, int m){    int i, s, sum;    for(i = 1; i <= n; i++)        f[i] = i;    sort(stu, stu+m, cmp);    for(i = s = sum = 0; i < m && s <= n-1; i++){        if(Merge(stu[i].u, stu[i].v)){            s++;            sum += stu[i].w;        }    }    if(s == n-1)        return sum;    else        return -1;}int main(){    int i, j, n, T, t;    int c[N], book[N];    scanf("%d", &T);    while(T--){        memset(book, 0, sizeof(book));        scanf("%d", &n);        for(i = 1; i <= n; i++){            scanf("%d", &c[i]);            if(prime(c[i]))                book[i] = 1;        }        t = 0;        for(i = 1; i <= n; i++){//数据处理            for(j = i+1; j <= n; j++){                if(book[i] || book[j] || prime(c[i]+c[j])){                    stu[t].u = i;                    stu[t].v = j;                    stu[t].w = min(min(c[i], c[j]), abs(c[i]-c[j]));                    t++;                }            }        }        printf("%d\n", Kruskal(n, t));    }    return 0;}