hdu2682 最小生成树

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2682

题目大意:n个城市,每个城市有初始欢乐值,城市AB有路连通如果A的欢乐值为质数或者B的欢乐值为质数或者A的欢乐值+B的欢乐值为质数,权值为min(A,min(B , |A-B|))。问将所有城市连在一起的最小花费。


思路:根据规则建图后,求最小生成树。


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;
//#pragma comment(linker, "/STACK:102400000,102400000")
#define maxn 2000050
#define MOD 1000000007
#define p 1000000007
#define mem(a , b) memset(a , b , sizeof(a))
#define LL long long
#define ULL unsigned long long
#define FOR(i , n) for(int i = 1 ;  i<= n ; i ++)
typedef pair pii;
const long long INF= 0x3fffffff;

int n , m;
int prime[maxn];
int a[605];
int vis[605];
int dist[605];
int graph[605][605];


struct node
{
    int v , w;
    bool friend operator<(node n1 , node n2)
    {
        return n1.w > n2.w;
    }
}cur;
vectorv[605];

void is_prime()
{
    for(int i = 0 ; i < maxn ; i ++) prime[i] = 1;
    prime[1] = 0;
    prime[0] = 0;
    for(int i = 2 ; i *i < maxn ; i ++)
    {
        if(prime[i] == 1)
        {
            int j = 2 * i;
            while(j < maxn)
            {
                prime[j] = 0;
                j += i;
            }
        }
    }
}


LL prime3(int cur)
{
    int index;
    LL sum = 0;
    memset(vis, 0, sizeof(vis));
    vis[cur] = 1;
    for(int i = 0; i < n; i ++)
    {
        dist[i] = graph[cur][i];
    }

    for(int i = 1; i < n; i ++){

        int mincost = maxn;
        for(int j = 0; j < n; j ++)
        {
            if(!vis[j] && dist[j] < mincost)
            {
                mincost = dist[j];
                index = j;
            }
        }

        vis[index] = 1;
        sum += mincost;

        for(int j = 0; j < n; j ++)
        {
            if(!vis[j] && dist[j] > graph[index][j])
            {
                dist[j] = graph[index][j];
            }
        }
    }
    return sum;
}


int main()
{
    is_prime();
    int t;
    while(scanf("%d" , &t) != EOF)
    {
        while(t--)
        {
            scanf("%d" , &n);
            int flag = 0 , tmp;
            mem(vis , 0);
            for(int i = 0 ; i < n ; i++) scanf("%d" , &a[i]);
            for(int i = 0 ; i < n; i ++)
            {
                for(int j = 0 ; j < n;  j ++)
                {
                    graph[i][j] = maxn;
                }
            }
            for(int i = 0 ; i < n ; i ++)
            {
                flag = 0;
                for(int j = 0 ; j < n ; j ++)
                {
                    if(prime[a[i]] || prime[a[j]] || prime[a[i] + a[j]])
                    {
                        tmp = maxn;
                        flag = 1;
                        tmp = min(tmp , a[i]);
                        tmp = min(tmp , a[j]);
                        tmp = min(tmp , abs(a[i] - a[j]));
                        graph[i][j] = min(graph[i][j] , tmp);
                        graph[j][i] = min(graph[j][i] , tmp);
                    }
                }
                if(!flag) break;
            }
            if(!flag)
            {
                printf("-1\n");
                continue;
            }
            printf("%lld\n" , prime3(0));
        }
    }
    return 0;
}


你可能感兴趣的:(图论)