zoukankan      html  css  js  c++  java
  • hdu 2682(最小生成树)

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

    思路:一个裸的最小生成树,先打个素数表,然后就是连边了。dfs判断是否连通,连通的话就是kruskal求最小生成树了。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<cmath>
      6 using namespace std;
      7 #define MAXN 666
      8 struct Edge{
      9    int u,v,w;
     10 }edge[MAXN*MAXN];
     11 bool map[MAXN][MAXN];
     12 bool prime[2222222];
     13 int parent[MAXN];
     14 bool mark[MAXN];
     15 int value[MAXN];
     16 int n,m,sum;
     17 
     18 void Initiate(){
     19    memset(prime,true,sizeof(prime));
     20    prime[0]=prime[1]=false;
     21    for(int i=2;i*i<=2222000;i++){
     22       if(prime[i]){
     23          for(int j=i*i;j<=2222000;j+=i){
     24             prime[j]=false;
     25          }
     26       }
     27    }
     28 }
     29 
     30 void dfs(int u){
     31    mark[u]=true;
     32    for(int i=1;i<=n;i++){
     33       if(map[u][i]&&!mark[i])dfs(i);
     34    }
     35 }
     36 
     37 int cmp(const Edge &p,const Edge &q){
     38    return p.w<q.w;
     39 }
     40 
     41 int Find(int x){
     42    int s;
     43    for(s=x;parent[s]>=0;s=parent[s])
     44    ;
     45    while(s!=x){
     46       int tmp=parent[x];
     47       parent[x]=s;
     48       x=tmp;
     49    }
     50    return s;
     51 }
     52 
     53 void Union(int R1,int R2){
     54    int r1=Find(R1);
     55    int r2=Find(R2);
     56    if(r1==r2)return ;
     57    if(parent[r1]<parent[r2]){
     58       parent[r1]+=parent[r2];
     59       parent[r2]=r1;
     60    }else {
     61       parent[r2]+=parent[r1];
     62       parent[r1]=r2;
     63    }
     64 }
     65 
     66 
     67 int main(){
     68  //  freopen("1.txt","r",stdin);
     69    Initiate();
     70    int _case;
     71    scanf("%d",&_case);
     72    while(_case--){
     73       scanf("%d",&n);sum=m=0;
     74       for(int i=1;i<=n;i++)scanf("%d",&value[i]);
     75       memset(mark,false,sizeof(mark));
     76       memset(map,false,sizeof(map));
     77       for(int i=1;i<=n;i++){
     78          for(int j=i+1;j<=n;j++){
     79             if(prime[value[j]]||prime[value[i]]||prime[value[i]+value[j]]){
     80                map[i][j]=map[j][i]=true;
     81                edge[m].u=i;
     82                edge[m].v=j;
     83                edge[m++].w=min(min(value[i],value[j]),abs(value[i]-value[j]));
     84             }
     85          }
     86       }
     87       dfs(1);
     88       bool flag=true;
     89       for(int i=1;i<=n;i++)if(!mark[i]){ flag=false;break; }
     90       if(!flag){ puts("-1");continue; }
     91       memset(parent,-1,sizeof(parent));
     92       sort(edge,edge+m,cmp);
     93       for(int i=0;i<m;i++){
     94          int u=Find(edge[i].u);
     95          int v=Find(edge[i].v);
     96          if(u!=v){
     97             sum+=edge[i].w;
     98             Union(u,v);
     99          }
    100       }
    101       printf("%d\n",sum);
    102    }
    103    return 0;
    104 }
    View Code
  • 相关阅读:
    如何使用SQL语句 查看存储过程的内容
    sl第一篇
    winForm连接数据库(sqlserver2005)
    Format
    dual使用
    ThreadLocal与事务
    oracle中的常用函数
    Oracle中merge into的使用
    API设计中token的思路
    SVN常用功能
  • 原文地址:https://www.cnblogs.com/wally/p/3118902.html
Copyright © 2011-2022 走看看