文章标题 HDU 2686 : Tree (最小生成树+普通筛)
来源:互联网 发布:阿里云总裁 编辑:程序博客网 时间:2024/06/05 16:46
Tree
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个点,每个点有一个权值,然后如果两个点a,b之间有连边当a、b、a+b中至少存在一个是素数,如果能连边,边的权值为 Min(Min(VA , VB),|VA-VB|),即a、b、|a+b|中的最小值,然后要我们求这n个的最小生成树,如果没法形成生成树就输出-1。
分析:先预处理出200000内的素数,然后对于任意两个点看是否能连边。然后跑一下kurskal就行了。
代码:
#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <queue>#include <set>#include <map>#include <algorithm>#include <math.h>#include <vector>using namespace std;int n; struct node { int u,v,w; bool operator <(const node &t)const { return w<t.w; }}edge[605*605];//边集 int fa[1000006];//并查集 bool prime[2000005];//标记是否是素数 int a[605];int find(int x){//并查集 return fa[x]==x?x:fa[x]=find(fa[x]);}void getprime(){//预处理出素数 memset (prime,true,sizeof (prime)); prime[0]=prime[1]=false; for (int i=2;i<=2000000;i++){ if (prime[i]){ for (int j=i*2;j<=2000000;j+=i){ prime[j]=false; } } }} int judge(int a,int b){//判断是否能连边 if (prime[a]||prime[b]||prime[a+b]){ return min((int)fabs(a-b),min(a,b)); } return -1;//不能连边直接输出-1 }int main(){ getprime();//预处理 int T; scanf ("%d",&T); while (T--){ scanf ("%d",&n); for (int i=0;i<n;i++){ scanf ("%d",&a[i]); } for (int i=0;i<=1000000;i++)fa[i]=i;//初始化 int cnt=0; for (int i=0;i<n-1;i++){ for (int j=i+1;j<n;j++){ int w=judge(a[i],a[j]); if (w!=-1){//判断能否加边 edge[cnt++]=(node){i,j,w}; } } } sort(edge,edge+cnt);//排序 int sum=0; int ans=0; for (int i=0;i<cnt;i++){ int fu=find(edge[i].u); int fv=find(edge[i].v); if (fu!=fv){ sum++; ans+=edge[i].w; fa[fu]=fv; } if (sum==n-1)break; } if (sum!=n-1)printf ("-1\n"); else printf ("%d\n",ans); } return 0;}
- 文章标题 HDU 2686 : Tree (最小生成树+普通筛)
- 文章标题 HDU 4786 : Fibonacci Tree(最小生成树--kruskal+并查集)
- 文章标题 HDU 2489 : Minimal Ratio Tree (最小生成树+状态压缩二进制思想)
- 文章标题 HDU 3371 : Connect the Cities(最小生成树--Kruskal+并查集)
- 文章标题 HDU 2122: Ice_cream’s world III (最小生成树+kruskal)
- 文章标题 HDU 1875: 畅通工程再续(最小生成树)
- hdu Minimal Ratio Tree(最小生成树---prim)
- HDU 2489 Minimal Ratio Tree(数据结构-最小生成树)
- HDU 2489 Minimal Ratio Tree(图论-最小生成树)
- HDU - 4786 Fibonacci Tree (最小生成树)
- HDU-#4786 Fibonacci Tree(最大最小生成树)
- hdu 2682 Tree 最小生成树 (并查集)
- hdu 4786 Fibonacci Tree(最小生成树)
- HDU-4786 Fibonacci Tree(最小生成树[Kruskal])
- HDU-2489 Minimal Ratio Tree(最小生成树[Prim])
- HDU 4786 Fibonacci Tree(最小生成树)
- hdu 4786 Fibonacci Tree(最小生成树)
- HDU 2489 Minimal Ratio Tree(最小生成树)
- UEFI简介
- lvm重名问题解决
- 数据库范式
- 新的开始
- 如何直接在github网站上更新你fork的repo
- 文章标题 HDU 2686 : Tree (最小生成树+普通筛)
- gcd
- SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)
- Linux mutex 封装
- IPLImage图像访问图片像素
- 7.26机房报零赛——无尽的矩阵【kmp+hash】
- ubuntu16.04登录界面循环 无法登录
- hadoop的端口简介
- PB 按指定长度截取中文