hdoj 2682 Tree(最小生成树+打表)
2015-11-23 15:53
483 查看
Tree
Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2107 Accepted Submission(s): 610
Problem Description
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
建图比较难,其他比较模板! 代码: 库鲁斯卡尔:
#include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> using namespace std; #define N 1100 #define INF 0x3f3f3f3f int a ,prime[1000000+100],set ; struct node { int strart; int end; int dist; }num[370000]; bool cmp (node a,node b) { return a.dist<b.dist ; } void dabiao()//打表,以免超时 { int i,j; memset(prime,0,sizeof(prime)); for(i=2;i<1000000+100;i++) { if(!prime[i]) for(j=2*i;j<1000000+100;j+=i) prime[j]=1; } prime[1]=1; } int find(int p) { int temp,child=p; while(p!=set[p]) p=set[p]; while(child!=p) { temp=set[child]; set[child]=p; child=temp; } return p; } void merge(int x,int y) { int fx=find(x); int fy=find(y); if(fx!=fy) set[fx]=fy; } int minxe(int a,int b,int c) { if(a>b) a=b; if(a>c) a=c; return a; } int main() { int t; scanf("%d",&t); dabiao(); while(t--) { int i,j,k=1,n,outcome=0; scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d",&a[i]); for(i=1;i<=n;i++) for(j=i+1;j<=n;j++) { num[k].strart =i; num[k].end =j; if(!prime[a[i]]||!prime[a[j]]||!prime[a[i]+a[j]]) { num[k].dist=minxe(a[i],a[j],abs(a[i]-a[j])); } else num[k].dist =INF; k++; } sort(num,num+k,cmp); for(i=1;i<=n;i++) set[i]=i; int flag=1; for(i=1;i<k;i++) { if(find(num[i].strart )!=find(num[i].end )) { if(num[i].dist ==INF) { flag=0; break; } outcome+=num[i].dist ; merge(num[i].strart ,num[i].end ); } } if(!flag) { printf("-1\n"); continue; } if(outcome>=INF) printf("-1\n"); else printf("%d\n",outcome); } return 0; }
普里姆:
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<math.h> #define INF 0x3f3f3f #define N 1100 int a ,n; int map ,prime[1000000+100]; void dabiao()//打表求素数 { int i,j,k; memset(prime,0,sizeof(prime)); for(i=2;i<1000000+100;i++) { if(!prime[i]) for(j=2*i;j<1000000+100;j+=i) prime[j]=1; } prime[1]=1; } int min(int a,int b,int c)//求最小值 { if(a>b) a=b; if(a>c) a=c; return a; } void prim()//求最小树 { int mincost,next=0,i,j,k,result=0; int visit ,cost ; memset(visit,0,sizeof(visit)); for(i=0;i<n;i++) { cost[i]=map[0][i]; } visit[0]=1; for(i=1;i<n;i++) { mincost=INF,next=0; for(j=0;j<n;j++) { if(!visit[j]&&cost[j]<mincost) { mincost=cost[j]; next=j; } } if(!next) { printf("-1\n"); return ; } visit[next]=1; result+=mincost; for(j=0;j<n;j++) { if(!visit[j]&&cost[j]>map[next][j]) cost[j]=map[next][j]; } } if(result) printf("%d\n",result); else printf("-1\n"); } int main() { int t; scanf("%d",&t); dabiao(); while(t--) { int i,j,k; scanf("%d",&n); for(i=0;i<n;i++) scanf("%d",&a[i]); for(i=0;i<n;i++) { map[i][i]=0; for(j=i+1;j<n;j++) { if(!prime[a[i]]||!prime[a[j]]||!prime[a[i]+a[j]]) map[i][j]=map[j][i]=min(a[i],a[j],abs(a[i]-a[j])); else map[i][j]=map[j][i]=INF; } } prim(); } return 0; }
相关文章推荐
- 命令行快速技巧:如何定位一个文件
- jquery+CSS实现的多级竖向展开树形TRee菜单效果
- cmd tree命令 以树形格式罗列文件
- 推荐8款jQuery轻量级树形Tree插件
- tree 以树形格式罗列文件
- EasyUI Tree+Asp.net实现权限树或目录树导航的简单实例
- E3 tree 1.6在Firefox下显示问题的修复方法
- js树形控件脚本代码
- 详解图的应用(最小生成树、拓扑排序、关键路径、最短路径)
- 最小生成树算法之Prim算法
- 使用C语言实现最小生成树求解的简单方法
- swing中Tree与滚动条用法实例分析
- Spark Decision Tree
- 最小生成树算法——Prim和Kruskal算法的实现
- 带check的treeView
- extjs 4 treepanel locked and expand
- JQuery EasyUI 实现tree的右键菜单
- flex tree 的两个小技巧
- Tree.log
- gnome文件管理器(nautilus)树形结构文件窗口 多窗口